c++ - 从指向子变量的指针转换为指向父变量的指针是否安全?

标签 c++ pointers

以下代码有效(在 ideone、Borland BCB 6 和 gcc 上)

#include <stdio.h>

class Base {
private:
    Base **BPtr;
public:
    Base(void *Ptr) {
        BPtr = (Base **)Ptr;
        *BPtr = this;
    }

    virtual ~Base() {
        if(BPtr) *BPtr = NULL;
        printf("Base aufgelöst\n");
    }
};

class Child : public Base {
    public:
    Child(void *Var) : Base(Var) {}
    ~Child() {
        printf("Child aufgelöst\n");
    }
};

int main() {
    Child *Ptr = NULL;
    new Child(&Ptr);
    printf("Childptr: %p\n", Ptr);
    delete Ptr;
    printf("Childptr: %p\n", Ptr);
    return 0;
}

上面程序的输出是:

Childptr: 0x9cc0008
Child aufgelöst
Base aufgelöst
Childptr: (nil)

这正是我所期望和想要的。

我的问题很简单:这真的安全还是只是看起来有效?因为首先将 Child 类型的指针隐式转换为 void *,然后将其转换为 Base ** 或者这是否存在任何明显(或隐藏)的问题?

非常感谢。

编辑: 由于对我的意图似乎有点误解:

这个“黑客”的唯一目的是NULL有问题的变量,一旦对象被销毁以保护我自己不小心忘记手动为NULL变量并可能在以后访问无效内存。

该变量必须且不会用于访问类的任何其他功能。

然而,我之前也尝试(和工作)的是以下内容:

void FreeFunc(void *Ptr) {
    if(Ptr) {
        Base **BPtr = (Base **)Ptr;
        delete *Ptr;    //Calls Destructors
        *Ptr = NULL;
    }
}

到目前为止,从我在这里收到的回复来看,哪个似乎更糟糕?

最佳答案

将 Child * 转换到 Base * 是安全的。将 Child** 转换到 Base** 并不是因为它们不相关。这样做的问题是,如果我转换为 void * 然后转换为 Base**,我现在可以将 Base * 分配给 Derived * 类型的指针,如下所示:

#include <iostream>

class Base
{
public:
    virtual void Foo() { std::cout << "Base::Foo" << std::endl; }
};

class Child : public Base
{
public:
    virtual void Foo() { std::cout << "Child::Foo" << std::endl; }
    virtual void Bar() { std::cout << "Child::Bar" << std::endl; }
};


void main()
{
    Child *d = new Child();
    Base *b = d;

    Child **d2 = &d;
    Base **b2 = (Base **)(void *)d2; // Force it

    *b2 = new Base(); // Whoops!  Child *d now points to an instance of Base *

    d->Bar();
}

关于c++ - 从指向子变量的指针转换为指向父变量的指针是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26359334/

相关文章:

c++ - Windows 7 64 位 C++ malloc 失败

c - 将 2D 数组传递给采用指针的函数

c - 如何将 double 组传递给 C 中的函数?

C 指针算术困惑

c++ - 有没有办法提示用户使用什么数据类型作为模板 C++

c - 操纵指针指向的内容

c++ - <inherit from parent or PROJECT DEFAULTS> 的默认值的 Visual Studios(主要是 2012 pro)文件位置

c++ - std::map 如何在没有比较函数的情况下将一对作为键映射到它的值

c++ - C++ 怎么知道容器类有 push_back 函数?

c++ - 关于构造函数中数据成员数组的大括号初始化的问题?