从虚函数返回派生指针

Returning a Derived pointer from a virtual function

class Base
{
public:
    // This version of getThis() returns a pointer to a Base class
    virtual Base* getThis() { std::cout << "called Base::getThis()\n"; return this; }
    void printType() { std::cout << "returned a Base\n"; }
};
 
class Derived : public Base
{
public:

    Derived* getThis() override { std::cout << "called Derived::getThis()\n";  return this; }
    void printType() { std::cout << "returned a Derived\n"; }
};



int main()
{
    Derived d;
    Base *b = &d;
    d.getThis()->printType(); // calls Derived::getThis(), returns a Derived*, calls Derived::printType
    b->getThis()->printType(); // calls Derived::getThis(), returns a Base* !! Why ?
 
    return 0;
}

这会打印:
称为 Derived::getThis()
返回一个 Derived
称为 Derived::getThis()
返回了一个 Base

调用b->getThis()->printType()时;为什么 b->getThis returns 指向 Base 的指针?不导出 ?

When calling b->getThis()->printType(); why b->getThis returns a pointer to Base ?

因为b是指向Base的指针。由Base::getThis编辑的指针return的类型是指向Base.

的指针

not to Derived ?

因为 Base::getThis 没有 return 指向 Derived 的指针。

注意指针的静态类型为Base,动态类型仍为Derived

多态性允许基础 class 呈现基础 class 接口,但以派生的 class 方式表现。多态地返回一个派生的 class 打破了这个模型,因为基指针的持有者将没有可靠的接口可以使用。

如果您有一个指向基类的指针 class 但确实必须使用派生类型 class 您必须 static_castdynamic_cast 指向您所在的派生类型使用 class (在你的例子中是在 main 函数中)。在 C++ 中进行转换可能不安全,因此您最好尽可能依赖多态性。

这就是 virtual 所做的。您告诉编译器 b 指向 Base。除非您使用多态性,否则它不会神奇地知道它 实际上 指向 Derived。您可以通过将 virtual 放在函数声明中来实现。如果你不这样做,你就不会得到多态调用。