c++ - 在被重新分配的类的构造函数中使用变量的地址

标签 c++ oop

<分区>

我一直在调试一个涉及 std::function(从 std::bind 创建)的问题,该问题归结为一个更基本的问题。

下面是一个示例,但简而言之,它是关于这样一种情况:类以一种或另一种方式在其构造函数中存储指向自身(或实例变量)的指针,然后类本身被重新分配。从我的实验来看,存储的指针似乎将不再指向类(或其实例变量)。我想知道避免这些问题的最佳做法是什么?

一个例子:

#include <iostream>

class Interface
{
public:
    Interface() {};
    virtual ~Interface() {};

    virtual void callback() = 0;
};

class B
{
public:
    B() : interface(NULL) {};
    virtual ~B() {};

    void set_interface(Interface* interface)
    {
        this->interface = interface;
    }

    void print()
    {
        std::cout << "B is at: " << this << std::endl;
        std::cout << "     Interface (A) from B is at: " << interface << std::endl;
    }

private:
    Interface* interface;
};

class A : public Interface
{
public:
    A()
    {
        b.set_interface(this);
    };
    virtual ~A() {};

    virtual void callback()
    {
        std::cout << "Callback" << std::endl;
    }

    void print()
    {
        std::cout << "A is at: " << this << std::endl;
        b.print();
    }

private:
    B b;
};


int main(int argc, char** argv)
{
    A a;
    a.print();

    std::cout << "------" << std::endl;
    a = A();
    a.print();

    return 0;
}

当我在我的机器上运行它时,我得到:

A is at: 0x7ffdb8910af0
B is at: 0x7ffdb8910af8
     Interface (A) from B is at: 0x7ffdb8910af0
------
A is at: 0x7ffdb8910af0
B is at: 0x7ffdb8910af8
     Interface (A) from B is at: 0x7ffdb8910b10

所以,起初一切都很好。 B 指向接口(interface)的指针指向A 的地址。但是,在重新分配 (a=A()) 之后,指向接口(interface)的指针不再指向 A!我意识到这是因为当 A 的构造函数正在运行以创建第二个实例时,它位于一个新的内存位置并将接口(interface)指针存储到这个新的内存位置。当 a 然后被重新分配时,对象被移动到旧位置,这使指向接口(interface)的指针无效。

这对我来说似乎是一个常见的用例。是否应该始终避免在对象的构造函数中引用内存?

在我的例子中,我想绑定(bind)一个回调函数并将它传递给一个类成员,看来我不能在构造函数中做,必须在以后做?

最佳答案

A 错误:

A()
{
    b.set_interface(this);
};

您为 A 定义了一个构造函数,它处理资源:自身。根据rule of 0/3/5 , A 应该有一个用户定义的复制构造函数和一个赋值运算符,如果有意义的话,它们的移动对应部分。

A()
{
    b.set_interface(this);
};

A(A const&)
{
    b.set_interface(this);
}

A& operator=(A const&)
{
    b.set_interface(this);
    return *this;
}

关于c++ - 在被重新分配的类的构造函数中使用变量的地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51963581/

相关文章:

java - 了解 equals-实现 : type-check and THEN type-cast

c++ - 为什么这个 type_traits 代码给我一个整数到指针转换警告?

c++ - 当我从虚拟基派生 D 时,为什么 VS2015 中的 sizeof(D) 增加了 8 个字节?

python - 在类方法中返回 self - 这是好方法吗?

php - 按页面 ID 过滤数据对象 SilverStripe 3

javascript - javascript 中 "this."的不当使用

c++ - 使用 WinApi 函数计算文件中的数字

c++ - Qt Creator 的 intellisense 认为 min 和 max 已定义,即使它们没有定义

c++ - FillConsoleOutputCharacter/WriteConsoleOutput 和特殊字符

javascript - 向现有js对象添加多个属性