c语言 调用父类方法,C++居然能用父类指针(里面存的也是父类)调用子类(子类独有的)函数?...

昨天问另外一个问题的时候, 今天早上有人回复给出了这样一段代码, 我试着运行了一下, 结果却大大出乎我的意料 :

class Father

{

public:

virtual void func1() { std::cout << "Father" << std::endl; }

virtual ~Father(){}

};

class Son :public Father

{

public:

virtual void func1(){ std::cout << "Son1" << std::endl; }

void func2(){ std::cout << "Son2" << std::endl; }

virtual ~Son(){}

};

class Factory

{

private:

Father* myFather;

public:

void setFun(Father* m_Father) { myFather = m_Father; }

Father* getFun() { return myFather;};

};

int main()

{

Father *m_Father = new Father();

Factory* m_Factory = new Factory();

m_Factory->setFun(m_Father );

m_Factory->getFun()->func1();

dynamic_cast<Son*>(m_Factory->getFun())->func2();

///

return 0;

}

运行结果是 :

Father

Son2

这让我感觉特别的奇怪 :

首先对于

main

中的变量

m_Father

, 他的静态类型和动态类型都是

Father指针

, 之后使用

dynamic_cast<Son*>

进行强制转换, 按照我的设想, 只有当

m_Father

的动态类型, 也就是实际指向一个

Son

的时候, 转换才能够成功, 然而这里不但成功转换, 同时还调用了

Son

独有的函数

fun2

, 这不是太奇怪了吗?

你试试在子类里加个数据成员然后在调用func时打印它。

你要理解在C++里,类的成员函数跟C里面的函数没什么本质区别,只不过是内存里的一段代码。你这里的fun2也一样,当你把指针变成Son*类型时,你调用

(Son*)->func2()

,C++只会把它拼成

Son$func2...

这样的一个函数签名,然后到符号表里面去查这个函数签名对应的内存位置,然后执行函数

在程序中

dynamic_cast<Son*>(m_Factory->getFun())

并没有转换成功,是个空指针,但空指针上依然可以调用成员函数,因为能寻址成功

类的对象实例中,内存布局中只存放成员变量,有virtual会再加一个vptr,类的成员函数是单独存放的。

如果一段代码里的类没有任何成员变量,也不涉及虚函数,即使你用一个指向NULL的类指针来调用,同样会成功。这就类似于c语言调用函数。

一看就是被c++的语法糖毒害的患者,哈哈。对于这两个类其实本质上都继承了father类。本质都是包含了指向father的指针而已。强制转换是取转换对象为基准的并集。所以只取了son中的属性作为转换的属性。而他俩都继承了father所以转换是没问题的

73bccf0c0b4af35beddca4274520fb45.png

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值