c ++危险的铸造代码

Abe*_*der 0 c++ polymorphism inheritance dynamic-cast static-cast

我很确定这是危险的代码.但是,我想检查是否有人知道究竟会出现什么问题.

假设我有这个类结构:

class A {
protected:
  int a;
public:
  A() { a = 0; }        
  int getA() { return a; }
  void setA(int v) { a = v; }
};

class B: public A {
protected:
  int b;
public:
  B() { b = 0; }
};
Run Code Online (Sandbox Code Playgroud)

然后假设我想要一种自动扩展类的方法,如下所示:

class Base {
public:
   virtual ~Base() {}
};

template <typename T>
class Test: public T, public Base {};
Run Code Online (Sandbox Code Playgroud)

我能做出的一个非常重要的保证是既Base不会也不Test会有任何其他成员变量或方法.它们本质上是空类.

(可能)危险的代码如下:

int main() {
  B *b = new B();

  // dangerous part?
  // forcing Test<B> to point to to an address of type B
  Test<B> *test = static_cast<Test<B> *>(b);

  //
  A *a = dynamic_cast<A *>(test);
  a->setA(10);
  std::cout << "result: " << a->getA() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

做这样的事情的理由是我使用类似于Test的类,但为了使它能够正常工作,必须创建一个新的实例T(即Test),同时复制传递的实例.如果我可以将Test指向T的内存地址,那将是非常好的.

如果Base没有添加虚拟析构函数,并且由于Test没有添加任何内容,我认为这段代码实际上是可以的.但是,添加虚拟析构函数会让我担心类型信息可能会添加到类中.如果是这种情况,则可能会导致内存访问冲突.

最后,我可以说这个代码在我的计算机/编译器(clang)上运行正常,但这当然不能保证它不会对内存做坏事和/或不会在另一个编译器/机器上完全失败.

Mar*_*som 5

Base::~Base删除指针时将调用虚析构函数.由于B没有适当的vtable(在此处发布的代码中根本没有),因此不会很好地结束.

它只适用于这种情况,因为你有内存泄漏,你永远不会删除test.