【问题标题】:Use reference to initialize class members使用引用初始化类成员
【发布时间】:2020-12-08 07:40:19
【问题描述】:

我一直觉得我不应该使用引用来初始化类成员,因为

  1. 我不知道引用的生命周期和
  2. 如果类外部的引用值发生变化,相应的类成员也会更改为新值。

但是在测试了下面的代码之后,我就一头雾水了……

class Test
{
public: 
    Test(int& i) :m_i(i) {}
    int m_i;
};

class Test3
{
public:
    Test3(int& i) :m_i(i) {}
    const int& m_i;
};

int main()
{
    {
        std::cout << "\n// Test 1" << std::endl;
        int i = 10;
        Test oTest(i);
        printf("oTest.i = %d\n", oTest.m_i);

        i = 20;
        printf("oTest.i = %d\n", oTest.m_i);
    }
    {
        std::cout << "\n// Test 1.1" << std::endl;
        int* i = new int;
        *i = 10;
        Test oTest(*i);
        printf("oTest.i = %d\n", oTest.m_i);

        *i = 20;
        printf("oTest.i = %d\n", oTest.m_i);

        delete i;
        printf("oTest.i = %d\n", oTest.m_i);
    }
    {
        std::cout << "\n// Test 3" << std::endl;
        int i = 10;
        Test3 oTest(i);
        printf("oTest.i = %d\n", oTest.m_i);

        i = 20;
        printf("oTest.i = %d\n", oTest.m_i);
    }

    {
        std::cout << "\n// Test 3.1" << std::endl;
        int* i = new int;
        *i = 10;
        Test3 oTest(*i);
        printf("oTest.i = %d\n", oTest.m_i);

        *i = 20;
        printf("oTest.i = %d\n", oTest.m_i);

        delete i;
        printf("oTest.i = %d\n", oTest.m_i);
    }

    return 0;
}

输出如下:

// Test 1
oTest.i = 10
oTest.i = 10          <---- Why not 20?

// Test 1.1
oTest.i = 10
oTest.i = 10          <---- Why not 20?
oTest.i = 10          <---- Why not some garbage number?

// Test 3
oTest.i = 10
oTest.i = 20

// Test 3.1
oTest.i = 10
oTest.i = 20
oTest.i = 20          <---- Why not some garbage number?

非常感谢您的评论。

【问题讨论】:

    标签: c++ class reference constants


    【解决方案1】:

    您的 Test(int&amp; i) :m_i(i) 调用 copy 构造函数,并且由于您的字段是 int,而不是 int&,因此测试 1 和 1.1 始终打印原始 10。

    在测试 3.1 中,没有要求访问已被释放/删除的内存会产生垃圾。 (有些调试编译器故意在释放的内存中放入一个不同的模式,但这是它们调试性质的一部分。)你的玩具程序中没有任何东西改变i指向的值,所以你“逍遥法外”。在企业程序中,您会得到一个很难找到的“Heisenbug”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-27
      • 1970-01-01
      相关资源
      最近更新 更多