c++ - 对象的地址可以改变吗?
问题描述
我想使用一个std::map
(或概率std::unordered_map
),我在其中插入自定义对象键和双精度值,例如std::map<CustomClass,double>
. 对象的顺序无关紧要,只是(快速)查找很重要。我的想法是插入对象的地址/指针,因为它已经定义了一个比较器,即std::map<CustomClass*,double>
在 Pointers as key in map C++ STL 中,已经回答说可以做到这一点,但我仍然有点担心可能会有以后难以捕捉的副作用。
具体来说:程序运行时对象的地址可以改变吗?这会导致我在地图中查找的未定义行为吗?
测试程序可以是:
auto a = adlib::SymPrimitive();
auto b = adlib::SymPrimitive();
auto c = adlib::mul(a,b);
auto d = adlib::add(c,a);
// adlib::Assignment holds std::map which assigns values to a,b
auto assignment = adlib::Assignment({&a,&b},{4,2});
// a=4, b=2 -> c=8 -> d=12
adlib::assertEqual(d.eval_fcn(assignment), 12);
这是用户代码,因此用户可能会将变量放入向量等。
更新:答案让我考虑用户可能插入SymPrimitives
向量,一个简单的场景是:
std::vector<adlib::SymPrimitive> syms{a,b};
auto assignment = adlib::Assignment({&syms[0],&syms[1]},{4,2}); // not allowed
这里的陷阱是它syms[0]
是一个副本a
并且具有不同的地址。要知道,我可能会承担用户的责任。
解决方案
程序运行期间对象的地址可以改变吗?
不,对象的地址永远不会改变。
但是,当对象的生命周期结束时,对象可以在创建它的地址停止存在。
例子:
std::map<CustomClass*,double> map;
{
CustomClass o;
map.emplace(&o, 3.14);
}
// the pointer within the map is now dangling; the pointed object does not exist
还要注意,对来容器的一些操作会导致容器的元素占据一个新的对象,而旧的被销毁。在这样的操作之后,对这些元素的引用(一般意义上;这包括指针和迭代器)是无效的,并且尝试通过这些引用访问的行为是未定义的。
推荐阅读
- hibernate - Nonstrict-read-write 中的脏读是什么?
- reactjs - 找不到所需的“intl”对象。
需要存在于组件祖先中。在使用 wrapper.html() - spring-batch - Spring Batch CommandLineJobRunner 带参数
- html - 在 javascript 中添加 CSS 选择器
- angular - 手风琴不能正常工作,应该一次打开一个
- reactjs - React @material-ui/core - v4.11.0 - “createMuiTheme 函数被重命名为 createTheme” 控制台错误
- mongodb - 如何使用 go mongo 驱动程序获取和检查 mongodb 索引选项
- ethereum - 如何将收获代币添加到农业合同中?
- javascript - 带有 proto loader 问题的 GRPC 连接设置
- postgresql - 使用 SSH 堡垒将 dbt 连接到 Postgres