最近遇到一个问题,类的循环引用。就是class A定义了class B的对象,class B中也定义了class A的对象。
错误的构造方式:采用直接new的方式,就会产生死循环的问题
//A.h
class B;
class A
{
public:
A();
~A();
private:
B* b;
};
//A.cpp
#include "A.h"
#include "B.h"
A::A()
{
b = new B();
}
A::~A()
{
delete b;
b = nullptr;
}
//B.h
class A;
class B
{
public:
B();
~B();
private:
A* a;
};
//B.cpp
#include "B.h"
#include "A.h"
B::B()
{
a = new A();
}
B::~B()
{
delete a;
a = nullptr;
}
讲真的,这样子写一看就知道有问题。但麻烦的是你还不知道怎么去改它。
下面来说说,这个问题如何优雅的解决。
正确的构造方式:使用类似于注册的方式去构造
//A.h
class B;
class A
{
public:
A();
~A();
private:
B * b;
};
//A.cpp
#include "a.h"
#include "b.h"
A::A()
{
b = new B;
b->setA(this);//划重点,类似于注册的方式去构造类B里的a
}
A::~A()
{
delete b;
b = nullptr;
}
//B.h
class A;
class B
{
public:
B();//划重点,并不需要实现
~B();
void setA(A * x);
private:
A * a;
};
//B.cpp
#include "b.h"
#include "a.h"
void B::setA(A * x)
{
a = x;
}
以上就是解决文件之间循环引用问题的方法。下面加大难度,三个文件之间的循环引用问题。
例子:class A中需要B的指针,class B中需要A的指针和C的指针,class C中需要B的指针。
解决的代码如下:
//A.h
class B;
class A
{
private:
B* b;
public:
A();
~A();
};
//A.cpp
#include "A.h"
#include "B.h"
A::A()
{
b = new B;
b->setA(this);
}
A::~A()
{
delete b;
}
//B.h
class A;
class C;
class B
{
private:
A* a;
C* c;
public:
B();
void setA(A* x);
void doSomething();
void doSomething2();
};
//B.cpp
#include "B.h"
#include "A.h"
#include "C.h"
B::B()
{
c = new C;
c->setB(this);
}
void B::setA(A* x)
{
a = x;
}
//C.h
class B;
class C
{
public:
B* b;
void setB(B* y);
};
//C.cpp
#include "C.h"
void C::setB(B* y)
{
b = y;
}
至此,三个文件的循环引用问题解决了。当然上述代码没有那么完整,如果跑不通,可以留言。
代码中的set函数好像也可以改成register注册,也就是注册指针,有个注册模式似乎与此相关,看后会补充博客。
原文地址:https://www.cnblogs.com/LampsAsarum/p/12101181.html
时间: 2024-10-04 18:31:41