美文网首页
C++ 编程技巧与规范(三)

C++ 编程技巧与规范(三)

作者: e196efe3d7df | 来源:发表于2020-11-20 14:33 被阅读0次

类的public继承(is-a关系)及代码编写规范

子类继承父类的方式有三种:public, protected, private
其中public继承表示的是is-a(is a kind of)关系。表示:通过子类产生的对象也一定是一个父类对象。能在父类上表现的行为,也必然能在子类上表现。父类出现的地方,必然能用子类来替换(里氏替换原则(LSP))。
父类表示一种更泛化的概念,子类表示一种更特化的概念

子类遮蔽父类的普通成员函数

如果父类和子类中有相同函数签名的普通成员函数,则子类中的函数会遮蔽掉父类中的函数。如下:

namespace demo5 {
    class Human {
    public:
        virtual ~Human() {};
        void eat() {
            std::cout << "人类吃" << std::endl;
        }
    };

    class Man :public Human {
    public:
        void eat() {
            std::cout << "男人吃" << std::endl;
        }
    };

    void mainFunc() {
        Man man;
        man.eat();          //父类的eat被子类遮蔽,调用的的是子类的eat
        man.Human::eat();   //强制调用父类被遮蔽的函数
    }
}

int main()
{
    demo5::mainFunc();
}

运行结果如下:


注:对于public继承,不建议也不应该让子类遮蔽父类的普通成员函数。既然在父类中是普通成员函数,则代表在子类中不会有不同行为。

父类的纯虚函数接口

纯虚函数的表现如下:

  1. 纯虚函数没有函数体,没有行为,需要子类定义具体行为。
  2. 纯虚函数就是interface,需要子类必须实现。
  3. 纯虚函数所在的类就是抽象类,不能生成该类的对象。
namespace demo5 {
    class Human {
    public:
        virtual ~Human() {};
    public:
        virtual void work() = 0;
        void eat() {
            std::cout << "人类吃" << std::endl;
        }
    };

    class Man : public Human {
    public:
        virtual void work() {
            std::cout << "重体力活" << std::endl;
        }
    };

    class Woman : public Human {
    public:
        virtual void work() {
            std::cout << "轻体力活" << std::endl;
        }
    };

    void mainFunc2() {
        Woman woman;
        woman.work();
    }
}

int main()
{
    demo5::mainFunc2();
}

父类的虚函数接口

虚函数接口,让子类继承父类的成员函数的接口及实现,表现如下:

  1. 子类可以提供自己的新实现。
  2. 子类不提供自己的实现,则会使用父类的实现
  3. 可以同时使用子类和父类的实现。
namespace demo6 {
    class Human {
    public:
        virtual ~Human() {};
    public:
        virtual void avlf() {
            std::cout << "人类75岁" << std::endl;
        }
    };

    class Man : public Human {
    public:
        virtual void avlf() {
            std::cout << "男人70岁" << std::endl;
        }
    };

    class Woman : public Human {
    public:
        virtual void avlf() {
            //调用父类
            Human::avlf();
            //子类自身的实现
            std::cout << "女人80岁" << std::endl;  
        }
    };

    void mainFunc() {
        Woman woman;
        Man man;
        woman.avlf();
        man.avlf();
    }
}

int main()
{
    demo6::mainFunc();
}

为纯虚函数制定实现体

有这样一种需求:

  1. 强制让子类实现该函数。
  2. 需要一些公共行为放在父类的该函数中。

也就是结合纯虚函数和虚函数的功能。是不是有些骚?其实是可以实现。纯虚函数也可以有自己的函数体:

namespace demo7 {
    class Human {
    public:
        virtual ~Human() {};
    public:
        virtual void work() = 0;
    };

    void Human::work()
    {
        std::cout << "人类干活" << std::endl;
    }

    class Man : public Human {
    public:
        virtual void work()
        {
            Human::work();
            std::cout << "男人:重体力活" << std::endl;
        }
    };

    class Woman : public Human {
    public:
        virtual void work()
        {
            Human::work();
            std::cout << "女人:轻体力活" << std::endl;
        }
    };

    void mainFunc() {
        Woman woman;
        Man man;
        woman.work();
        man.work();
    }
}

int main()
{
    demo7::mainFunc();
}

运行结果如下:


类的public继承综合范例

--省略了

public继承关系下的代码编写规范

综上:

  1. 父类的普通成员函数,子类不应该去覆盖。如果需要覆盖,则需要在父类中将该普通成员函数修改为虚函数。
  2. 父类的纯虚函数,实际就是一个接口,子类必须要去实现该接口。且包含纯虚函数的父类为抽象类,不能实例化。
  3. 父类的普通虚函数(非纯虚函数),不但定义一个接口,而且还允许有自己的实现。子类可以继承该实现,也可以覆盖该实现,也会混用该实现
  4. 非必要使用public继承时,就不要使用public继承,必须要满足is-a关系。

类的private继承

private继承,不是is-a关系,是一种组合关系。确切的说是组合关系中的is-implemented-in-terms-of关系(根据...实现出...)。
一般优先考虑使用普通的组合关系,只有一些特殊情况和必要情况下,比如一些protected成员,private成员,虚函数等时才考虑使用private继承,来表示这种组合关系。

相关文章

  • C++ 编程技巧与规范(三)

    类的public继承(is-a关系)及代码编写规范 子类继承父类的方式有三种:public, protected,...

  • C++ 编程技巧与规范(五)

    不能被拷贝构造和拷贝赋值的类对象 delete 用delete这种方式,需要自己提供构造函数。 加入以上处理后,当...

  • C++ 编程技巧与规范(二)

    拷贝构造函数和拷贝复制运算符的书写 如下: 对象自我赋值产生的问题 对象的自我赋值,会产生一些问题,比如: A的赋...

  • C++ 编程技巧与规范(一)

    静态对象的探讨 类中静态成员变量 静态成员变量,需要先声明,然后再定义。如果没有使用到该静态成员变量,则可以不用定...

  • C++ 编程技巧与规范(四)

    组合关系 has-a 关系 has-a 关系也称为 is-part-of关系。下面的定义了这种关系: 可以是说是 ...

  • 极客班第一周学习笔记

    初识C++ C++是在C之上基于对象,面向对象的编程语言。c++相比c在编程上更加模块化,具象化。 C++代码规范...

  • C++面向对象高级编程(上)笔记

    1.培养规范、大气的编程习惯 C++的学习过程可以分为C++语言与C++标准库两个部分,不必太在乎版本。标准库一般...

  • C++ 编程规范

    C++ 编程规范 这是一本 由两位世界顶级专家联袂巨献,适合所有层次 C++程序员 的 C++ 界20年集大成之作...

  • C++ 编程规范

    组织 不要拘泥于小节 在高警告级别干净利落地进行编译 使用自动构建系统 适用版本控制系统 在代码审查上投入 设计 ...

  • C++编程规范

    序 C++用法很多,包容性也比较强。一个C++的工程可能包含了各种各样没见过的用法。本篇内容主要是参照谷歌C++标...

网友评论

      本文标题:C++ 编程技巧与规范(三)

      本文链接:https://www.haomeiwen.com/subject/pwcliktx.html