c++ - 构造函数参数的引用成员按值传递
问题描述
这是一个示例代码,其中包含对构造函数参数的引用成员按值传递:
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"
?是否与返回对函数本地对象的引用类似?
解决方案
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).
推荐阅读
- c++ - 为表示一个或多个操作的 C++ 函数查找 int 参数的类型安全替换
- git - 在drupal 8中安装模块时作曲家抛出git错误
- typescript - 将类型分配给可能不需要解析的 JSON 类型
- java - 活动中的 Android 工作室名称选项卡
- sql - 我可以合并或加入这些表吗?
- c# - 如何在 ASP.NET 中使用视图模型?
- php - 即使 WP_DEBUG=true,Wordpress 也不会写入 debug.log
- quill - Quill:如何获取包含样式的 html 数据?
- python - 当您在 if 逻辑语句中调用修改函数时,是否会编辑 2D 列表?
- javascript - 如何使用 Javascript 本地存储从 HTML 文本框中存储值?