c++类型转换以获得访问权限

标签 c++ casting virtual-destructor

我正在编写一个类(析构函数是虚拟的),其中的对象只能使用回收器类的对象来删除。但是我发现任何人都可以在不知道我的回收器类的情况下删除该类的对象。

请考虑以下示例:

class A
{
public:
    A() {qDebug() << "cTor: A";}

protected:
    virtual ~A() {qDebug() << "dTor: A";}
};

class B
{
public:
    virtual ~B() {cout << "dTor: B";}

protected:
    B() {cout << "cTor: B";}
};

A *a = new A;
delete (B*)a; // How is this possible !!??

输出:

cTor: A
dTor: A

如果可能,在不使 A 的析构函数非虚拟的最终子类的情况下,我可以做些什么来防止这种情况发生?

最佳答案

对于您上面提到的情况,您只是很幸运,B 的析构函数的地址与 A 的析构函数的地址在指针的偏移量方面相同。

虚拟析构函数只是对象 vftable 中的另一个条目。如果你只是访问内存地址,你可以调用任何析构函数(不管他有多私有(private))。

这是一个代码示例,展示了这些事情是如何运作的:

class A
{
public:
    virtual void foo() {printf("foo !");};
};
class B
{
public:
    virtual void bar() {printf("bar !");};
}; 
...
A* a = new A();
((B*)a)->bar();

显然我可以通过调用 B->bar 来调用 A foo 而 B 甚至没有 A !!!!魔法 ?不。恰好 B->bar 与 A->foo 具有相同的地址。考虑到您的示例,A 的析构函数与 B 的析构函数具有相同的地址。

关于您的评论,如果这对于图书馆开发 PoV 是安全的:

如果开发者不知道正确的转换方式,那不是你的问题,或者如果开发者真的想破坏你的库,他会的。您的工作是在正确使用事物时提供工作代码。如果库的用户想要从你的库中重新解释 cast 对象或使用其他非标准的、未定义的行为,你将无能为力(例如,一些随机的家伙想要使用 malloc 分配对象不是你的错......玩得开心和那个家伙!)。

关于c++类型转换以获得访问权限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27999168/

相关文章:

swift - 类型转换/多态性如何与 Swift 中的这种嵌套闭包类型一起工作?

c++ - 虚拟析构函数和未定义的行为

C++:指向具有可变数量参数的函数的函数指针

c++ - 尝试创建自定义字符串类,但我不断收到 C2440 和 E0415 错误

c++ - 将动态结构数组复制到另一个 C++

java - 在除法之前将 int 类型转换为 float。我真正需要哪些类型转换,我可以删除哪些类型转换,为什么?

postgresql - 如何使 VARCHAR 成为 PostgreSQL 中字符串的首选类型?

c++ - 类 COM 接口(interface)警告非虚拟析构函数

c++ - 使用向上转型时的虚拟析构函数

c++ - 使用 std::atomic 实现无锁结构,Dtor 崩溃