C++中抽象类的继承

26 阅读1分钟
#include <stdio.h>

class A {
public:
	virtual void print() = 0;

	A() { printf("%s %d enter\n", __func__, __LINE__); }
};

class B : public A {
public:
	B() { printf("%s %d enter\n", __func__, __LINE__); }
};

class C : public B {
public:
	virtual void print() { printf("hello\n"); }

	C() { printf("%s %d enter\n", __func__, __LINE__); }
};

int main()
{
	C c;	// 正确

	// B b;	// 错误

	// A a;    // 错误

	return 0;
}

运行后的打印:

A 7 enter
B 12 enter
C 19 enter

当去掉26行注释,编译报错:

test_2.cpp: In function ‘int main()’:
test_2.cpp:26:4: error: cannot declare variable ‘b’ to be of abstract type ‘B’
   26 |  B b; // 错误
      |    ^
test_2.cpp:10:7: note:   because the following virtual functions are pure within ‘B’:
   10 | class B : public A {
      |       ^
test_2.cpp:5:15: note:  ‘virtual void A::print()’
    5 |  virtual void print() = 0;
      |               ^~~~~

总结:

在上面的示例中,有A、B、C三个类,其中A是一个包含virtual虚函数的抽象类,
B类继承A类但不实现虚函数,C类继承B类且实现了虚函数。

  1. 一个类(B类)如果继承了含有虚函数的抽象类(A类),则 子类(B类)同样是抽象类,是无法实例化的,尝试对其实例化则会编译时报错;
  2. 子类(C类)实例化,构造顺序是先基类部分、后子类部分(先后顺序是A->B->C);
  3. 子类(C类)实例化时,虽然调用到了基类(B类)的构造函数,但只是构造子类中的基类部分,并非构造一个B类型的对象,所以不会报1中的编译错误。