我正在将一些代码移植到Windows并且很难过.还有的是,在启动自动运行的指针复制到一个指针,而退出再次运行删除指针的指针,如果它不为空一些代码.
我创建了一个示例程序来重现行为
int main()
{
// Pointer to a Pointer, current crash.
InterfaceClass** ptrptr;
ConcreteTwo* object = new ConcreteTwo();
ptrptr = (InterfaceClass**)(&object); // cast is required for some reason.
delete *ptrptr; // Crash here.
// Single pointer, works fine.
InterfaceClass* ptrptr;
ConcreteTwo* object = new ConcreteTwo();
ptrptr = object;
delete ptrptr;
// There are other cases where there are only 3 classes in the hierarchy.
// This also works fine.
InterfaceClass** ptrptr;
ConcreteOne* object = new ConcreteOne();
ptrptr = (InterfaceClass**)(&object);
delete *ptrptr;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
类层次结构如下所示.基类是一个带有一些纯虚函数的接口,并且被整个程序中的许多类包含,使得许多对象可能从多个地方继承它.因此,具体实现必须使用"public virtual InterfaceClass"扩展它.在此示例中,删除"虚拟"可解决崩溃问题.
class InterfaceClass {
public:
virtual ~InterfaceClass() {};
InterfaceClass() {}
};
class ConcreteClass : public virtual InterfaceClass {
public:
ConcreteClass() { }
virtual ~ConcreteClass() {}
};
class ConcreteOne : public ConcreteClass
{
public:
ConcreteOne(void) {}
virtual ~ConcreteOne(void) {}
};
class ConcreteTwo : public ConcreteOne
{
public:
ConcreteTwo(void) {}
virtual ~ConcreteTwo(void) {}
};
Run Code Online (Sandbox Code Playgroud)
那么你是否熟悉指针的类型几乎与它指向的类型无关?换句话说,如果你认为T1从T2继承T1*也继承自T2*?那是错的.现在,这如何适用于您目前的情况?
InterfaceClass** ptrptr;
ConcreteTwo* object = new ConcreteTwo();
ptrptr = (InterfaceClass**)(&object); // cast is required for some reason.
Run Code Online (Sandbox Code Playgroud)
这是C风格转换的一个主要问题.好的,所以它节省了一些水平空间,但你甚至知道你刚刚做了什么样的演员表?这不是你的想法.您实际上从ConcreteTwo*类型执行了reintpret_cast到一个不相关的类型InterfaceClass*!现在指针地址与你说的类型无关.
然后你将一个重新解释的指针类型扔进删除,这会立即导致你违反自己的括约肌.
| 归档时间: |
|
| 查看次数: |
158 次 |
| 最近记录: |