【发布时间】:2021-03-12 22:33:47
【问题描述】:
我正在使用可以容纳大型数据结构的外部库。调用它返回指向它管理的对象的指针:
class ExternalLib {
public:
int* GetLargeObject() { return &large_object; };
private:
int large_object = 1;
};
我正在尝试为这个外部库编写一个包装器,它可以保存对我感兴趣的大型数据结构的 const 引用:
class ExternalLibraryWrapper {
public:
ExternalLibraryWrapper() : large_object_ref(*ext.GetLargeObject()){};
private:
ExternalLib ext;
const uint &large_object_ref;
};
但是,我收到编译器警告:
引用成员 'large_object_ref' 绑定到一个临时对象,其生命周期将比构造对象的生命周期短 [clang: dangling_member]
据我了解,ext.GetLargeObject() 返回一个指向(*this).ext.large_object 地址的临时指针。编译器不应该知道构造的对象&large_object_ref 实际上并没有绑定到临时对象吗?
【问题讨论】:
-
我认为问题在于您试图将
const引用存储到不是const的东西开始,因此编译会创建一个临时来满足绑定。这将解释警告。为什么你需要存储参考?简单地存储原始指针并按原样使用它有什么问题?class ExternalLibraryWrapper { public: ExternalLibraryWrapper() : large_object_ptr(ext.GetLargeObject()){}; private: ExternalLib ext; int *large_object_ptr; }; -
这在我看来基本上是粗略的。您正在使用初始化列表中的另一个成员,假设该对象已经构造。情况可能并非如此,这可能是编译器以迂回方式发出此警告的原因。
-
共享指针仅应在共享对象所有权时使用。这不是这里的情况。
large_object的所有权定义明确。是否应该按照他们的方式定义是另一回事。 -
@paddy 我故意对成员变量进行排序,以便在分配
large_object_ref之前构造ext。 -
@RemyLebeau:添加
const不应导致临时实现!我们一直通过 const-reference 接受参数而不期望副本。我的水晶球说实际代码中存在类型不匹配,允许隐式转换——或者编译器错误。
标签: c++ pointers reference c++17 lifetime