美文网首页
★03.关于单继承

★03.关于单继承

作者: iDragonfly | 来源:发表于2017-06-30 21:23 被阅读0次

基类总是要写虚析构函数

class A {
public:
    virtual ~A() = default;
};

通过设置析构函数为纯虚函数来让类称为抽象基类

代码

class A {
public:
    virtual ~A() = 0 {}
};

函数virtual属性的传递性

class A {
public:
    virtual void fun() { std::cout << "fun" << std::endl; }
};

class B : public A {
public:
    // 没有写virtual,却有virtual属性
    void fun() { std::cout << "fun2" << std::endl; }
};

class C : public B {
public:
    // 没有写virtual,却有virtual属性
    void fun() { std::cout << "fun3" << std::endl; }
};

int main(void) {
    B * b = new C;
    b->fun();
    delete b;
    return system("pause");
}

拷贝移动控制成员的定义

简述

拷贝移动控制成员包括:拷贝构造函数、拷贝赋值函数、移动构造函数、移动赋值函数。

代码

operator=返回值有错误,待修正

class A {
public:
    // 拷贝构造函数
    A(const A & a) = default;

    // 移动构造函数
    A(A && a) = default;

    // 拷贝赋值函数
    A & operator=(const A & a) { return (*this); }

    // 移动赋值函数
    A & operator=(A &&) = default;

    virtual ~A() = default;
};

class B : public A {
public:
    // 调用基类的拷贝构造函数
    B(const B & b) : A(b) {}

    // 调用基类的移动拷贝构造函数
    B(B && b) : A(std::move(b)) {}

    // 不要忘记调用基类的拷贝赋值函数
    B & operator=(const B & b) {
        A::operator=(b);
        // 执行一些操作...
        return (*this);
    }

    B & operator=(B && b) {
        // 不要忘记调用基类的移动赋值函数
        A::operator=(std::move(b));
        // 执行一些操作...
        return (*this);
    }
};

单继承中,继承基类构造函数

代码

class A {
public:
    A() = default;

    A(int) { std::cout << "A(int)" << std::endl; }

    A(double) { std::cout << "A(double)" << std::endl; }
};

class B : public A {
public:
    using A::A;

    B(int) { std::cout << "B(int)" << std::endl; };
};

int main() {
    B b1(9);
    B b2(9.9);
    return system("pause");
}

输出结果

B(int)
A(double)

基类成员的可访问性

class A {
public:
    void abc() {}
};

class B : public A {
public:
    void fun1() { abc(); }

};

class C : protected A {
public:
    void fun1() { abc(); }
};

class D : private A {
public:
    void fun1() { abc(); }
};

class BB : public B {
public:
    void fun2() { abc(); }
};

class CC : public C {
public:
    void fun2() { abc(); }
};

class DD : public D {
public:
    void fun2() { abc(); }       // 无法访问
};

int main() {
    B b;
    b.abc();
    C c;
    c.abc();       // 无法访问
    D d;
    d.abc():       // 无法访问
    return system("pause");
}

构造或析构时,不呈现多态性

简述

在构造或析构基类时,如果调用了某个虚函数,则这个虚函数使用与当前构造函数或析构函数所属类型相对应的虚函数版本。

代码

class A {
public:
    // 在构造函数体内,fun()函数不会表现出多态性。
    A(int) { fun(); }

    virtual void fun() { std::cout << "A::fun()" << std::endl; }
};

class B : public A {
public:
    B() : A(1) {}

    virtual void fun() { std::cout << "B::fun()" << std::endl; }
};

int main() {
    B b;
    return system("pause");
}

输出结果

A::fun()

访问控制符仅作用于自身成员和基类成员

class A {
protected:
    int a;
};


class B : public A {
public:
    void fun(A & temp) {
        a = 3;
        temp.a = 3;         // 错误
    }
};

改变基类成员的可访问性

class A {
public:
    int i;
    int j;
};

class B : private A {      // 私有继承
public:
    using A::i;            // 改变i的访问控制为public
protected:
    using A::j;            // 改变i的访问控制为protected
};


int main() {
    B b;
    b.i = 3;
    return system("pause");
}

重写函数发生的遮掩问题及其解决方案

class A {
public:
    virtual void fun() { do_fun(); }

    virtual void fun(int a) { do_fun(a); }

    virtual void fun(char c) { do_fun(c); }

protected:
    virtual void do_fun() {}

    virtual void do_fun(int) {}

    virtual void do_fun(char) {}
};


class B : public A {
public:
    void fun() {}
};


int main() {
    B b;
    // 继承其中一个fun函数,导致遮掩了其他基类fun函数版本。
    b.fun('c');
    // 解决方案:通过使fun()函数调用dofun(),而派生类重载do_fun()函数来避免遮掩问题。
    return system("pause");
}

delete基类指针数组是未定义行为

class A {
};

class B : public A {
};

int main() {
    A * a = new B[10];
    delete[] a;         // 错误
    return system("pause");
}

不能使用间接非虚基类的构造函数

class A {
public:
    A() {}
};

class B : public A {
public:
    // 允许使用直接非虚基类构造函数
    B() : A() {}
};


class C : public B {
public:
    // 不允许使用间接非虚基类构造函数
    C() : A() {}
};

相关文章

  • ★03.关于单继承

    基类总是要写虚析构函数 通过设置析构函数为纯虚函数来让类称为抽象基类 代码 函数virtual属性的传递性 拷贝移...

  • Java面向对象三大特性之继承

    继承 一、继承的特点 Java只支持单继承单继承 多继承 单继承、多继承优缺点①单继承优点:提高了代码的复用性,让...

  • Python-学习之路-08 OOP -02

    单继承和多继承 单继承:每个类只能继承一个类 多继承:每个类可以继承多个类 单继承的多继承的优缺点 菱形继承/钻石...

  • Python继承

    python可以分为单继承和多继承; 单继承: 单继承就是继承一个类的时候,现在我们定义一个Student类 然后...

  • 继承单例的脚本

    继承Monobehaviour的单例 不继承Monobehaviour的单例

  • 继承(单继承,多继承)

    将共性的内容放在父类中,子类只需要关注自己特有的内容 python中所有的内容都是对象,所有的对象都直接或间接继承...

  • iOS 中几种多继承的实现方式

    单继承与多继承概念 继承是面向对象的基本特征之一,在具体语言的语法上设计有两种形式:多继承与单继承。 单继承 一个...

  • Python学习基础知识之 面向对象的简单基础,常见操作(单继承

    目录 一、继承介绍以及单继承 1.1程序中的继承(extend) 1.2单继承 1.3多继承 二、子类重写父类的同...

  • 单继承

    父类.方法(self,*args)和super(父类名,self).方法 当super(父类名,self).方法 ...

  • iOS 多继承实现方式

    一、单继承与多继承概念 继承是面向对象的基本特征之一,在具体语言的语法上设计有两种形式:多继承与单继承。 1.单继...

网友评论

      本文标题:★03.关于单继承

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