对基类成员var的引用会导致访问冲突

时间:2018-04-15 13:59:48

标签: c++ reference derived-class

我已经将派生类的成员var定义为对基类的成员var的引用。我这样做是因为在派生类中,引用的名称比基类中原始变量的名称更有意义。

现在我正在创建一个char的缓冲区,其大小足以包含派生类的对象。我定义了一个指向派生类的指针,并使用static_cast将其指向缓冲区。

如果派生类的成员函数使用基类中定义的原始名称取消引用基类成员var,则没有问题。

但如果使用引用的名称取消引用它,我会收到内存访问冲突。

  1. 为什么会有不同的行为?
  2. 我如何实现我想要做的事情,即在派生类中用不同的名称引用变量?

    class B {
    public:
        int x;
        B () : x(10) {}
    };
    
    class D : public B {
    public:
        int &y{ x };
        // No problem here:
        inline bool IsXTen () { return ((x == 10) ? true : false); }
        // Memory Access Violation occurs here:
        inline bool IsYTen () { return ((y == 10) ? true : false); }
    };
    
    int main(int argc, char* argv[])
    {
        char buf[sizeof (class D)] = { 0 };
        void *pVoid = buf;
        class D *pd = static_cast<class D*>(pVoid);
    
        if (pd->IsXTen ()) {
            return 1;
        }
    
        if (pd->IsYTen ()) {
            return 2;
        }
    
        return 0;
    }
    

2 个答案:

答案 0 :(得分:1)

引用可能存储为对象内存布局中的指针(请参阅Why do references occupy memory when member of a class? )。您没有调用初始化该引用/指针的构造函数,因此使用它是未定义的。

答案 1 :(得分:1)

正如评论中所提到的,你这样做的方式并没有构建对象。在这种情况下使用“placement new”来正确构建它:

char buf[sizeof (class D)] = { 0 };

// Class not initialized, constructors not called
// class D *pd = static_cast<class D*>(pVoid);

// Object is properly initialized
class D *pd = new (buf) D;