158
C++11引入final特殊标识符,可以使得类不能被继承
class B final {}; class D : public B {};
using A::A; 继承所有基类ctor
若基类constructor未被显式调用,基类的默认构造函数就会被调用
图片alt
构造函数链:父先子后析构函数链:子先父后
class P { public: void f() {} }; class C :public P { public: using P::f; //此处不带小括号* void f(int x) {} }; int main() { C c; c.f(); }
基类定义了虚同名函数,那么派生类中的同名函数自动变为虚函数
class P { public: f(){…} }; //父类 class C: public P { public: f(){…} }; //子类 main () { P p; C c; p.f(); //调用P::f() c.f(); //调用C::f() }
说明: 对象是什么类型,就调什么类型
class P { public: f(){…} }; //父类 class C: public P { public: f(){…} }; //子类 main () { P* ptr; P p; C c; ptr = &p; ptr->f(); // 调用P::f() ptr=&c; ptr->f(); // 调用P::f() }
说明: 指针是什么类型,就调什么类型
class P { public: virtual f(){…} }; //父类 class C: public P { public: f(){…} }; //子类,f自动virtual main () { P* ptr; P p; C c; ptr = &p; ptr->f(); //调用P::f() ptr=&c; ptr->f(); //调用C::f() }
说明: 函数虚,不看指针看真对象
class P { public: virtual f(){…} }; //父类 class C: public P { public: f(){…} }; //子类,f自动virtual main () { P p; C c; P& pr1 = p; pr1.f(); //调用P::f() P& pr2 = c; pr2.f(); //调用C::f() }
说明: 函数虚,不看引用看真对象
class A { public: virtual void foo() {} void bar() {} }; class B : public A { public: void foo() const override { // 错误: B::foo 不覆写 A::foo } // (签名不匹配) void foo() override; // OK : B::foo 覆写 A::foo void bar() override {} // 错误: A::bar 非虚 }; void B::foo() override {// 错误: override只能放到类内使用
override的价值在于:避免程序员在覆写时错命名或无虚函数导致隐藏bug
struct Base { virtual void foo(); }; struct A : Base { void foo() final; // A::foo 被覆写且是最终覆写 void bar() final; // 错误:非虚函数不能被覆写或是 final }; struct B final : A // struct B 为 final,不能被继承 { void foo() override; // 错误: foo 不能被覆写,因为它在 A 中是 final };
C++11引入final特殊标识符,指定派生类不能覆写虚函数
virtual double getArea() = 0; // 在Shape类中
#include <typeinfo> //使用typeid,需要包含此头文件 class A {}; A a{}; auto& t1 = typeid(a); if (typeid(A) == t1) { std::cout << "a has type " << t1.name() << std::endl; }