首页 > 解决方案 > 构造函数参数的引用成员按值传递

问题描述

这是一个示例代码,其中包含对构造函数参数的引用成员按值传递:

struct A
{
    A(std::string name): name_(name){}
    std::string name_;
};

struct B
{
    B(A a): a_(a)
    {
    }
    A& a_;
};

int main()
{
    std::unique_ptr<B> b;
    {
        A a("a");
        b.reset(new B(a));
    }
    b->a_.name_ = "b";

    return 0;
}

是否a_仍然引用此行中的现有对象b->a_.name_ = "b" ?是否与返回对函数本地对象的引用类似?

标签: c++c++11

解决方案


a_ 是否仍然引用此行中的现有对象 b->a_.name_ = "b" ?

没有。那是一个未定义的行为

特别是B构造函数

B(A a): a_(a)
{
}

生成一个悬空引用

参数的活跃度a仅限于构造函数调用的范围。一旦构造函数结束,对象a将被销毁。因此,您初始化的引用a_指向一个被破坏的对象。

但是,当您尝试访问它时:

b->a_.name_ = "b";

您实际上是在调用未定义的行为,因为该对象不再存在(这很糟糕!)。


是否与返回对函数本地对象的引用类似?

如果您返回对不再存在的对象的引用并尝试访问它,那么......仍然是相同的未定义行为:悬空引用。


附加说明

通过构建您的代码,以下更改仍然是错误的:

B(A& a): a_(a)
    {
    }

请注意,参数现在是通过引用传递的。

实际上,即使您不获取对象的副本,A当您尝试访问它时,引用的对象也会被销毁:

{ 
     A a("a");
     b.reset(new B(a));
}  // Here a will be destroyed because out of scope (as automatic variable).

推荐阅读