C++ 在unordered_list中存储和传递引用而不是值
C++ Storing and passing references instead of values in an unordered_list
我有一些代码可以很好地编译和运行,但按值传递对象:
AssetRepository AssetRepositoryFactory::getAssetRepository(std::string clientId)
{
std::unordered_map<std::string, AssetRepository>::iterator iterator = m_repositories.find(clientId);
if ( iterator != m_repositories.end())
{
return iterator->second;
}
else
{
AssetRepository repository = AssetRepository(clientId);
std::pair<std::string, AssetRepository> pair (clientId, repository);
m_repositories.insert(pair);
return repository;
}
}
我打算让这段代码做的是通过引用传递,但这可能是一个相当常见的新手C++开发人员错误。所以我试图通过更改以下代码来通过引用传递:
AssetRepository& AssetRepositoryFactory::getAssetRepository(std::string clientId)
{
std::unordered_map<std::string, AssetRepository&>::iterator iterator = m_repositories.find(clientId);
if ( iterator != m_repositories.end())
{
return iterator->second;
}
else
{
AssetRepository repository = AssetRepository(clientId);
std::pair<std::string, AssetRepository&> pair (clientId, repository);
m_repositories.insert(pair);
return repository;
}
}
不幸的是,我收到此错误:
HEAP[CGF_flight_controller.exe]: Invalid allocation size - c3d9e9e0 (exceeded fffdefff)
First-chance exception at 0x000007FEFD24B3DD in CGF_flight_controller.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x0000000002C6F4F0.
Microsoft Visual Studio C Runtime Library has detected a fatal error in CGF_flight_controller.exe.
那是如果我通过
AssetRepository repository = AssetRepositoryFactory::getInstance().getAssetRepository("clientId0");
或者,如果我打电话
AssetRepository &repository = AssetRepositoryFactory::getInstance().getAssetRepository("clientId0");
我得到
First-chance exception at 0x000007FEE72EAD7B (RTDynamics-vc11-md-64.dll) in CGF_flight_controller.exe: 0xC0000005: Access violation reading location 0x0000000000000028.
Unhandled exception at 0x000007FEE72EAD7B (RTDynamics-vc11-md-64.dll) in CGF_flight_controller.exe: 0xC0000005: Access violation reading location 0x0000000000000028.
我很难理解必须通过引用显式传递,因为我通常是 Java 开发人员。请有人帮我弄清楚吗?
这段代码是绝对错误的。
AssetRepository& function() {
[...]
AssetRepository repository = [...];
[...]
return repository; // by reference
// but "repository" gets destroyed...
}
您正在返回对函数返回后不存在的对象的引用。 别这样。 这被称为"悬空引用"(将其放入Google)。 只能使用对现有对象的引用。
问题就在这里:
std::unordered_map<std::string, AssetRepository&>
容器的值应为可分配的。 但引用不可分配。 声明它们时,您只能初始化它们一次,并且您不能让它们稍后引用其他内容。
但是您有一些解决方案:
像工作代码一样使用值。 并使用移动语义来降低复制值的成本。
在映射中使用指向资产存储库的指针:
std::unordered_map<std::string, AssetRepository*>
使用引用包装器使引用可分配。
有关更多信息和解决方案,请查看此问题:为什么我不能制作引用向量?
我
最终找到了一个解决方案,并合并了关于悬空引用的评论和改用指针的建议。
AssetRepository* AssetRepositoryFactory::getAssetRepository(std::string clientId)
{
std::unordered_map<std::string, AssetRepository>::iterator iterator = m_repositories.find(clientId);
if ( iterator != m_repositories.end())
{
AssetRepository repository = iterator->second;
return &(iterator->second);
}
else
{
AssetRepository repository = AssetRepository(clientId);
std::pair<std::string, AssetRepository> pair (clientId, repository);
m_repositories.insert(pair);
return getAssetRepository(clientId);
}
}
相关文章:
- 将对象数组的引用传递给函数
- 什么时候在C++中返回常量引用是个好主意
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 何时在引用或唯一指针上使用移动语义
- 如何在c++中使用引用实现类似python的行为
- 编译C++时未定义的引用
- Ctypes wstring通过引用传递
- c++r值引用应用于函数指针
- 理解c++中的引用
- C++取消引用指针.为什么会发生变化
- 如何修复此错误:未定义对"距离(浮点数,浮点数,浮点数,浮点数,浮点数)"的引用
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 强制转换为引用类型
- 引用一个已擦除类型(void*)的指针
- 向量元素的引用地址与它所指向的向量元素的地址不同.为什么
- 具有默认值的引用获取函数
- 如何使用基类指针引用派生类成员
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- 如何引用基类的派生类?