成员变量
在 C++ 中,持有引用对象本身不会导致循环引用。循环引用通常发生在两个或多个对象通过智能指针(如 std::shared_ptr)相互持有对方的指针,从而导致引用计数无法归零,进而导致内存泄漏。 引用(如 OtherClass&)只是对象的别名,不管理对象的生命周期,因此不会增加引用计数,也不会导致循环引用。
class A;
class B {
public:
B(A& a) : aRef(a) {}
private:
A& aRef;
};
class A {
public:
void setB(B* b) { bPtr = b; }
private:
B* bPtr;
};
B 持有 A 的引用,而 A 持有 B 的指针。这种情况下不会导致循环引用,因为引用不管理对象的生命周期。
引用的特性
引用是对象的别名,它并不拥有对象,也不会增加对象的引用计数。引用一旦初始化,就会一直引用同一个对象,并且在对象的生命周期管理方面不发挥作用。
不会导致循环引用的原因
由于引用不参与对象的引用计数,所以即使多个对象之间相互持有引用,也不会出现引用计数永远不为 0 的情况,也就不会产生循环引用。
创建销毁
#include <iostream>
class A {
public:
void show() const {
std::cout << "A::show()" << std::endl;
}
};
class B {
public:
B(A& a) : aRef(a) {} // 在构造函数中初始化引用
void display() const {
aRef.show();
}
private:
A& aRef; // 持有 A 的引用
};
int main() {
A a; // 创建 A 的实例
{
B b(a); // 创建 B 的实例,并传递 A 的引用
b.display(); // 调用 B 的方法,间接调用 A 的方法
} // B 的生命周期结束,aRef 也随之销毁,但 a 不受影响
a.show(); // A 的实例仍然存在,可以继续使用
return 0;
}
A 类有一个方法 show()。
B 类持有 A 类的引用 aRef,并在构造函数中初始化。
在 main 函数中,创建了 A 的实例 a,然后在一个作用域内创建了 B 的实例 b,并传递 a 的引用。
当 B 的实例 b 的生命周期结束时,aRef 也随之销毁,但 a 的实例仍然存在,可以继续使用。
这个示例说明了引用的生命周期与持有它的对象相同,但引用的销毁不会影响引用的对象。