我很确定这是危险的代码。但是,我想检查一下是否有人知道究竟会出现什么问题。
假设我有这个类结构:
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; }
};
然后假设我想要一种自动扩展类的方法,如下所示:
class Base {
public:
virtual ~Base() {}
};
template <typename T>
class Test: public T, public Base {};
我可以做出的一个非常重要的保证是,既没有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;
}
做这样的事情的基本原理是我正在使用一个类似于 Test 的类,但是为了让它当前工作,必须创建一个新的实例 T(即 Test),同时复制传递的实例。如果我可以将 Test 指向 T 的内存地址,那就太好了。
如果 Base 没有添加虚拟析构函数,并且由于 Test 没有添加任何内容,我认为这段代码实际上是可以的。但是,添加虚拟析构函数让我担心类型信息可能会添加到类中。如果是这种情况,那么它可能会导致内存访问冲突。
最后,我可以说这段代码在我的计算机/编译器(clang)上运行良好,尽管这当然不能保证它不会对内存造成坏事和/或不会在另一个编译器/机器上完全失败。