클래스가 부모 개체의 수명 이후에 액세스하면 안되는 개체에 대한 핸들 참조를 반환하는 것은 그리 이상적이지 않습니다. 방어 코딩을 돕기 위해 아래 패턴을 변경하는 가장 좋은 방법은 무엇입니까?반환 된 참조 수명에 대한 C++ 힌팅/경고
// '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++의 사용자를 막을 수 없습니다 알고 있지만, 이것이 내가 원하는 무엇의 대부분 것처럼 나는 적어도 사소한 우발적 인 사용에 대한 경고를 생성 할 수 있다면 달성하기.
기존 코드를 이해하고 있지만 유지해야하는 항목과 변경할 수있는 내용이 확실하지 않습니다. 포인터 나 참조에'handle()'의 결과를 저장하는 것을 멈춰야한다고 말하고 싶습니다. 직접 (예를 들어'a.handle(). methodOfB()'를 사용하거나'B b = a. – jsantander
@jsantander A <>는 래퍼 파기 시점에서 주변에서 잡히게 될 객체에 대한 평생 매니저 래퍼 (wrapper)이므로 불행히도 복사 의미가 적용되지 않습니다. 항상'a.handle.methodOfB() '를 호출하는 것은 확실히 가능하지만 래퍼보다 수명이 긴 참조를 저장하는 빌드 타임 감지 기능을 추가하여이 까다로운 인터페이스를 조금 더 열악하게 만들었습니다. – Jeff
이러한 참조 대신 std :: weak_ptr을 사용하는 것이 가장 이상적입니다. – berkus