C++子类和父类指针的转换,推荐使用dynamic_cast,需要注意的是,其实在C++里面还有其他的转换方式,这里先不做探究。我们在这里只做两个比较,分别是括号强制转换和dynimic_cast两个。


  先抛出结论,只有在父类有虚函数的时候,用 dyniamci_cast才有效。如果转换失败,返回NULL,转换成功,返回对应的指针。


测试1-<理想使用场影>:

#include <iostream>
using namespace std;
class Base{
public:
	void virtual Func()	{
		cout << "Base Func\n";
	}
};
class Child :public Base
{
public:
	void Func()	{
		cout << "Child Func\n";
	}
	void NewFunc()	{
		cout << "Child Newfunc\n";
	}
};
//测试用例
int main(){
	Base *b = new Child();
	b->Func();//输出Child Func, 这里基实是用了多态
			  //b->NewFunc();//错误 这个函数不是虚函数,不能多态调用
	Child *child1 = (Child *)b;//转换方式一不安全
	child1->NewFunc();//Child NewFunc

	Child *child2 = dynamic_cast<Child *>(b);//转换方式二安全方式
	if (child2 != NULL)	{
		child2->NewFunc();//Child NewFunc
	}
	return 0;
}

输出

Child Func
Child Newfunc
00A0B5D8
00A0B5D8
Child Newfunc

测试2-有虚函数类与无关类:

#include <iostream>
using namespace std;
class Base{
public:
	void virtual Func()	{
		cout << "Base Func\n";
	}
};
class Child :public Base
{
public:
	void Func()	{
		cout << "Child Func\n";
	}
	void NewFunc(){
		cout << "Child Newfunc\n";
	}

};
// 我们再增加一个不相关的类
class Person {
public:
	void NewFunc() {
		cout << "Person NewFunc" << endl;
	}
};
// 测试用例
int main() {

	Base *b = new Child();
	b->Func();//输出Child Func, 这里基实是用了多态
			  //b->NewFunc();//错误 这个函数不是虚函数,不能多态调用
	Person *person1 = (Person  *)b;//转换方式一不安全
	person1->NewFunc();//Child NewFunc
	cout << person1 << endl;

	Person *person2 = dynamic_cast<Person *>(b);//转换方式二安全方式
	cout << person2 << endl;
	if (person2 != NULL){
		person2->NewFunc();
	}
	return 0;
}

输出:

Child Func
Person NewFunc
010C8D20
00000000

可以很明显的看出,如果用的是两个不相关的类进行指针转换,那么用强转不会有任何错,而使用dynamic_cast则会报错,结果为NULL,即000000。至于为什么还会输出Person NewFunc是C++中,在类中的函数是不需要初始化的,只要取到这个类的指针,就可以调用这个函数,当然,如果在这个函数中调用了类中的相关属性,那以这个函数也会报错。

测式三-无虚函数类:

#include <iostream>
using namespace std;
class Base
{
public:
	void Func()	{
		cout << "Base Func\n";
	}
};
class Child :public Base
{
public:
	void Func()	{
		cout << "Child Func\n";
	}
	void NewFunc(){
		cout << "Child Newfunc\n";
	}
};

// 我们再增加一个不相关的类
class Person {
public:
	void NewFunc() {
		cout << "Person NewFunc" << endl;
	}
};

//测试用例
int main(){
	Base *b = new Child();
	b->Func();//输出Child Func, 这里基实是用了多态
			  //b->NewFunc();//错误 这个函数不是虚函数,不能多态调用
	Child *child1 = (Child *)b;//转换方式一不安全
	child1->NewFunc();//Child NewFunc
	cout << child1 << endl;
	Child *child2 = dynamic_cast<Child *>(b);//转换方式二安全方式
	cout << child2 << endl;
	if (child2 != NULL)	{
		child2->NewFunc();//Child NewFunc
	}
	return 0;
}

报错,无法正常正时行编绎。
输出:

错误	C2683	“dynamic_cast”:“Base”不是多态类型
错误(活动)		运行时 dynamic_cast 的操作数必须包含多态类类型	ConsoleApplication1	

注:如果在子类添加virtual,也是不能运行的。

Logo

NVIDIA官方入驻,分享最新的官方资源以及活动/会议信息,精选收录AI相关技术内容,欢迎大家加入社区并参与讨论。

更多推荐