C++返回的引用生存期的提示/警告
C++ hinting/warning for returned reference lifetimes
我有一个不太理想的情况,即类返回对父对象生存期后不应访问的对象的句柄引用。改变以下模式以帮助防御性编码的最佳方法是什么?
// 'A<T>' is a thin factory-style utility class with asynchronous consumers.
template <typename T>
struct A {
A() : h_(*(new T())) { /* ... */ }
~A() { /* h_ deleted or ownership passed elsewhere */ }
// What's the best way to indicate that these handles shouldn't be used after
// the destructions of the A instances?
T &handle() { return h_; }
private
T &h_;
};
struct B { /* ... */ };
int main() {
B *b1{nullptr};
{
A<B> a;
// Is there a good way to trigger detection that the reference is bound to
// a variable which will outlive its 'valid' local lifetime?
b1 = &a.handle();
B &b2(a.handle()); // this is reasonable though
b1->ok_action();
b2.also_alright();
}
b1->uh_oh();
}
我知道你不能真正阻止C++用户做大多数不安全的事情,但是如果我至少可以对像这样的琐碎意外使用生成警告,那将是我想要实现的大部分。
我冒昧地对你的情况做一些假设:
- 句柄指向由用户自行决定
A
生成的动态分配的对象。 - 句柄将在超出范围的地方传递
A
因此A
不能用作强制网关。
销毁句 - 柄指向的数据时必须销毁
A
,因此无法将自动垃圾回收应用于句柄。 - 到目前为止,编译时安全检查似乎是不可能的。您希望编码错误在运行时通过某种异常机制而不是自发崩溃表现出来。
考虑到这一点,这里有一个可能的解决方案:
在A
的构造函数中,分配某种信号对象S
该对象在A
被销毁时设置。使用shared_ptr
处理S
。A::handle
返回一个自定义句柄类H
其中包含一个B
句柄和一个要S
shared_ptr
。在 H
内创建一个取消引用运算符,用于验证A
是否仍然有效(未设置S
)或引发异常。当所有句柄过期时,S
将自动销毁。
对象 A 产生另一个 B 类的对象,让某人使用它,然后确保 B 在 A 之前被销毁?
与其返回 B 的实例,是否可以在 A 上定义一个获取 B 然后将其传递给某种委托(虚拟方法、函子、lambda 函数)的方法?这样,user 函数就嵌套在对 A 对象上的方法的调用中,因此在用户代码完成它正在执行的任何操作之前,从逻辑上讲,不可能销毁 A。
例如:
class A
{
public:
template <typename Functor>
void DoSomethingWithAnInstanceOfB(const char* whichB, Functor f)
{
B& bref = InternalLookupB(whichB);
f(bref);
}
};
这将查找正确的 B 实例,然后将其传递给任意函子。函子可以做任何它想做的事情,但它必须在 DoSomethingWithAnInstanceOfB() 返回之前返回,因此保证 A 的生命周期至少与 B 一样长。
- 警告处理为错误这里有什么问题
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- cppcheck在const std::string[]上引发警告
- GCC对可能有效的代码抛出init list生存期警告
- 如何在BST的这个简单递归实现中消除警告
- 关于std::move的使用,是否有编译警告
- g++ 在某个类成员未初始化时不发出警告
- 如何处理来自核心指南检查器的关于gsl::at的静态分析警告
- 使用typeid警告未使用的变量
- 示例C++项目编译中的警告
- 有没有办法提示用户使用哪种数据类型作为模板 c++
- 警告:在函数返回类型 [-Wignore 限定符] 时忽略类型限定符
- 如何修复编译器警告 C6386 和 C6385?
- 返回语句后的代码,没有警告
- 获取隐式转换溢出从无符号到已签名的警告
- 编译器警告:执行到达值返回函数的末尾而不返回值
- 在未链接的部分上生成警告
- 警告 C4552:">>":未使用表达式的结果
- 在没有警告提示的情况下打开文件
- C++返回的引用生存期的提示/警告