2013-03-10 78 views
2

首先,问题与 downcasting shared pointer to derived class with additional functionality is非常相似,其中有很好的答案。但我想解释为什么这是有效的(或不)和何时不使用共享指针。所以:派生指针只能添加方法时将基指针转换为派生指针的有效性

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相同的接口 。
  • 我希望能够将此模板库与我的基础对象一起使用
  • 由于附加功能,以上是不可能的。但是这些功能从基地实施是微不足道的。
  • 我也想尽可能高效率(避免转换和 间接引用)

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

回答

2

这是未定义的行为。无论它是否适用于任何给定的编译器,可能都是重点;一般来说,你不能依赖这个工作。 *

在你描述的场景中,听起来最好的解决方案就是创建一些以Base作为参数的免费函数。当然,如果所需的功能依赖于protected成员,那么您遇到了问题! (我不知道有一个很好的解决方案,除了找到一个方法来避免需要这样的访问。)


*即使你从来没有改变你的编译器是真的。编译器可以自由地假定所有的代码都是“正确的”,所以稍微改变你的代码可能会触发一个优化,使上述技巧无用。

(当然,我不会建议,这将肯定发生,只不过是表示可能

+0

感谢您的回答。但我不明白与链接问题的区别:第一个答案表明,如果Base有一个虚拟析构函数,这是有效的。我看到的唯一区别是使用共享ptrs,它真的很重要吗? (也注意派生只添加*方法*,没有成员,所以我期望相同的内存布局,因此希望所有这些都是有效的;) – rdrien 2013-03-11 09:01:23

+0

@rdrien:因为在那个问题中,有问题的对象确实是派生的。 – 2013-03-11 09:07:29

+0

是的,对不起,我错过了这一点! Thx再次。 – rdrien 2013-03-11 09:26:04

相关问题