C++居然能用父类指针(里面存的也是父类)调用子类(子类独有的)函数?
伊谢尔伦
伊谢尔伦 2017-04-17 14:21:02
0
4
539

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

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, 这不是太奇怪了吗?

伊谢尔伦
伊谢尔伦

小伙看你根骨奇佳,潜力无限,来学PHP伐。

reply all(4)
PHPzhong

You try adding a data member to the subclass and printing it when func is called.

Peter_Zhu

You have to understand that in C++, the member functions of a class are not essentially different from the functions in C. They are just a piece of code in memory. The same goes for fun2 here. When you change the pointer to Son* type and you call (Son*)->func2(), C++ will only spell it into a function signature like Son$func2..., and then go to the symbol table to check the function signature. Corresponding memory location, and then execute the function

In the program, dynamic_cast<Son*>(m_Factory->getFun()) is not converted successfully, it is a null pointer, but the member function can still be called on the null pointer, because the addressing is successful

黄舟

In the object instance of the class, only member variables are stored in the memory layout. If there is a virtual, a vptr will be added, and the member functions of the class are stored separately.
If the class in a piece of code does not have any member variables and does not involve virtual functions, even if you call it with a class pointer pointing to NULL, it will still succeed. This is similar to calling a function in C language.

大家讲道理

At first glance, it looks like a patient poisoned by the syntactic sugar of C++, haha. For these two classes, they actually inherit the father class. Essentially, it just contains a pointer to father. Coercion is a union based on the conversion object. So only the attributes in son are taken as the converted attributes. And they both inherited father, so the conversion is no problem

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template