从虚函数返回派生指针
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_cast
或 dynamic_cast
指向您所在的派生类型使用 class (在你的例子中是在 main 函数中)。在 C++ 中进行转换可能不安全,因此您最好尽可能依赖多态性。
这就是 virtual
所做的。您告诉编译器 b
指向 Base
。除非您使用多态性,否则它不会神奇地知道它 实际上 指向 Derived
。您可以通过将 virtual
放在函数声明中来实现。如果你不这样做,你就不会得到多态调用。
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_cast
或 dynamic_cast
指向您所在的派生类型使用 class (在你的例子中是在 main 函数中)。在 C++ 中进行转换可能不安全,因此您最好尽可能依赖多态性。
这就是 virtual
所做的。您告诉编译器 b
指向 Base
。除非您使用多态性,否则它不会神奇地知道它 实际上 指向 Derived
。您可以通过将 virtual
放在函数声明中来实现。如果你不这样做,你就不会得到多态调用。