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)上运行正常,但这当然不能保证它不会对内存做坏事和/或不会在另一个编译器/机器上完全失败.
Base::~Base删除指针时将调用虚析构函数.由于B没有适当的vtable(在此处发布的代码中根本没有),因此不会很好地结束.
它只适用于这种情况,因为你有内存泄漏,你永远不会删除test.
| 归档时间: |
|
| 查看次数: |
244 次 |
| 最近记录: |