C++ 当派生只添加方法时,将基指针强制转换为派生指针的有效性

C++ 当派生只添加方法时,将基指针强制转换为派生指针的有效性,c++,inheritance,extend,downcast,C++,Inheritance,Extend,Downcast,首先,这个问题非常类似于 ,那里有很好的答案。但我想解释一下为什么这是有效的(或无效的),以及何时不使用共享指针。因此: class Base { /* ... */ }; class Derived : public Base { public: void additionnalFunc(int i){ /* access Base members */ } }; int main(){ Base b; Derived* d = (Derived*) &b; // or s

首先,这个问题非常类似于 ,那里有很好的答案。但我想解释一下为什么这是有效的(或无效的),以及何时不使用共享指针。因此:

class Base { /* ... */ };

class Derived : public Base
{
public:
    void additionnalFunc(int i){ /* access Base members */ }
};

int main(){
Base b;
Derived* d = (Derived*) &b; // or static_cast ?
d->additionnalFunc(3); // works ok.
}
这与gcc的预期效果一样。那么我的问题是它安全/有效吗?有编译器或架构吗?若否,原因为何

为了解释这个问题的原因,这里是上下文

  • 我有“基本”对象
  • 我不能修改基类
  • 我有一组模板函数,它们需要相同的接口 作为基础,除了一些附加功能
  • 我希望能够将此模板库用于我的基本对象
  • 由于附加功能,上述操作是不可能的。但是 这些函数从基础上实现起来非常简单
  • 此外,我希望尽可能高效(避免转换和 间接法)

因此,如果上述技巧是有效的,它可能是一个很好的解决方案。。。但也许有更好的设计来解决这个问题?

这是未定义的行为。它是否能在任何给定的编译器上“工作”可能并不重要;一般来说,你不能指望这项工作*

在您描述的场景中,听起来最好的解决方案就是创建一些以
Base
为参数的自由函数。当然,如果所需的功能依赖于受保护的成员,那么您就有问题了!(我不确定是否有一个好的解决方案,除了找到一种避免需要这种访问的方法。)


*这是事实,即使你从未改变你的编译器。编译器可以自由地假设所有代码都是“正确的”,因此对代码的轻微更改可能会触发优化,从而使上述技巧无效

(当然,我不会建议这肯定会发生,只是说它可能会发生)

谢谢你的回答。但我不理解与我联系的问题的区别:第一个答案说,如果Base有一个虚拟析构函数,这是有效的。我看到的与我的案例的唯一区别是使用共享PTR,这真的重要吗?(还请注意,派生只添加方法,没有成员,因此我希望使用相同的内存布局,因此希望所有这些都是有效的;@rdrien:因为在这个问题中,所讨论的对象实际上是派生的。