C++实验在基类的构造函数中调用被子类重载的虚函数

子类重载虚函数

在C++中,子类可以重载基类的虚函数,这是C++语法中一个重要的多态

例如,ClassB继承自ClassA,且重载了基类的一个函数,则被调用时将会触发重载的版本:

#include<iostream>
using namespace std;

class ClassA
{
public:
	virtual void TestFunc() 
	{ 
		cout << "ClassA::TestFunc" << endl; 
	}
};

class ClassB : public ClassA
{
public:
	virtual void TestFunc() override
	{
		cout << "ClassB::TestFunc" << endl;
	}
};

int main()
{
	ClassB* pB = new ClassB();
	pB->TestFunc();
}

输出:

ClassB::TestFunc

这和指针的类型没有关系,就算将指针类型改为ClassA,只要对象仍旧是ClassB,那么结果一样:

int main()
{
	ClassA* pA = new ClassB();
	pA->TestFunc();
}
ClassB::TestFunc

问题

但这里有一个问题是:
一个ClassB类型的对象,只要重载了TestFunc,那么ClassA版本的TestFunc那在任何时候都不会被调用吗?

实验后发现并不是这样——在ClassB的构造函数中会调用ClassA版本的构造函数,而如果在ClassA的构造函数中调用了TestFunc,那么被调用的是ClassA的版本。
下面是实验:

实验在基类的构造函数中调用被子类重载的虚函数

ClassA的构造函数中调用会被重载的函数TestFunc

ClassA()
{
	TestFunc();
}

main中创建ClassB类型的对象

int main()
{
	ClassB* pB = new ClassB();
}

那么结果是:

ClassA::TestFunc

也就是说:
在基类的构造函数中调用会被子类重载的虚函数,调用的版本是基类的版本。

关于为何是这样,我还没有较深的理解。我不清楚C++标准中是否针对这种用法有明确的规定;也不确定编译器在处理这一问题上是否有差别。

不过,这一问题要留意,因为在实际编程时确实会造成困惑。

在基类的构造函数中调用纯虚函数会怎么样?

既然普通的虚函数不行,那么“纯虚函数”会怎么样呢?毕竟基类没有它的实现

实验1

TestFunc改为纯虚函数:

class ClassA
{
public:
	ClassA()
	{
		TestFunc();
	}
	virtual void TestFunc() = 0;
};

这样会出现链接错误:

1>testV.obj : error LNK2019: 无法解析的外部符号 "public: virtual void __cdecl ClassA::TestFunc(void)" (?TestFunc@ClassA@@UEAAXXZ),该符号在函数 "public: __cdecl ClassA::ClassA(void)" (??0ClassA@@QEAA@XZ) 中被引用
1>D:\0_WorkSpace\Cpp\TestMiscs\x64\Debug\TestMiscs.exe : fatal error LNK1120: 1 个无法解析的外部命令

实验2

那么再“耍一些诡计”:
让构造函数调用另一个函数,而后者去调用纯虚函数:

class ClassA
{
public:
	ClassA()
	{
		Test2();
	}
	virtual void TestFunc() = 0;
	void Test2()
	{
		TestFunc();
	}
};

编译成功了,然而运行时会报错:
在这里插入图片描述
看来,无论怎么样,在基类的构造函数中都无法调用被子类重载的函数。(至少在我目前的环境下是这样)

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值