static_pointer_cast<Derived> pReallyABase = static_pointer_cast<Derived>(pBase) 有效!为什么?
static_pointer_cast<Derived> pReallyABase = static_pointer_cast<Derived>(pBase) works! Why?
我不明白为什么会这样。pReallyABase是向下转换的shared_pointer<派生的>,指向基类实例。派生的>
我明白为什么编译器让我调用pReallyABase->onlyForDerived(),因为我将其定义为派生类指针,但为什么当我尝试使用该指针调用派生类函数时,我不会得到运行时错误?
class Base {
public:
virtual string whatAmI() {
return "I am a Base";
}
};
class Derived : public Base {
public:
virtual string whatAmI() {
return "I am a Derived";
}
string onlyForDerived() {
return "I can do Derived things";
}
};
int main(int argc, char *argv[]) {
shared_ptr<Base> pBase = shared_ptr<Base>(new Base);
shared_ptr<Derived> pReallyABase = static_pointer_cast<Derived>(pBase);
cout << pReallyABase->whatAmI() << endl;
cout << pReallyABase->onlyForDerived() << endl; //Why does this work?
return 0;
}
结果I am a Base
I can do Derived things
这是关于在c++中如何调用成员函数(非静态和非虚)的,《Inside c++ object model》一书对此有解释:
一个c++设计准则是非静态成员函数至少必须为与其类似的非成员函数一样有效。不应该有额外的开销用于选择成员函数实例。这是通过内部改造实现的将成员实例转换为等效的非成员实例。在这些转变之后它的每个调用也必须被转换:例如:
obj.magnitude();
是
magnitude_7Point3dFv(&obj);
和
ptr->magnitude();
是
magnitude_7Point3dFv(ptr);
正如上面的例子,函数onlyForDerived不使用类Derived的任何成员变量,所以它可以工作。但这是一个未定义的行为,我们不应该依赖它
通过将Base
对象视为Derived
,您将自动获得未定义行为,因此您看到的任何行为都是合法的。
在这种情况下,由于编译器"知道"派生指针的静态类型是Derived
,因此它能够调用该函数,尽管这样做是不合法的。
它不会引发运行时错误,因为它不必这样做(undefined就是undefined)。也就是说,如果函数是虚拟的,它可能会在大多数实现中崩溃,如果派生类具有派生函数引用的数据,它可能会崩溃或生成意想不到的输出。
相关文章:
- 为什么即使使用-cudart-static进行编译,库用户仍然需要链接到cuda运行时
- 如何处理 c++ 中类实现中的"invalid use of non-static data member"?
- 将sharet_ptr<Derived>转换为shared_ptr<Base>
- 从 std<Derived>::shared_ptr 的向量返回 std::shared_ptr<Base>
- 如何使用"derived input class"创建派生类?
- 收到错误"invalid use of non-static data member 'stu::n' "
- LNK1104:无法打开libpjproject-i386-Win32-vc14-Debug-Static.lib
- 我应该在 C++ 中何时/为什么使用 STATIC?
- 在VS2019项目中集成ImageMagick:x64-windows-static library
- 如何处理Boost Spirit X3导致Visual Studio 2019 "static initialization order fiasco"?
- "static char __ = []() -> char"的含义
- 如何从unique_ptr返回unique_ptr的引用<Derived><Base>?
- 当初始值设定项是基类名时'initializer does not name a non-static data member or base class'错误
- 如何将unique_ptr<derived>*转换为<base>unique_ptr*?
- <Base> <Derived> 具有相同原始指针共享引用的 shared_ptr 和 shared_ptr 实例是否计数?
- 无法在 DLL 中链接 SDL2-static.lib
- 如何摆脱C++中未解析的外部符号"private: static char"错误?
- 如何从 Eigen::MatrixBase <Derived>获取存储选项
- C++线程"Call to non-static member function without an object argument"
- 出现这种错误的原因是什么"invalid use of non-static data member "