由于循环依赖,因此对某些类使用前向声明:
//B.h
class A;
class B
{
public:
void foo(A* a);
};
typedef SmartPtr<B> BPtr;
//A.h
class B;
class A
{
public:
void foo(B* b);
};
typedef SmartPtr<A> APtr;
现在,假设我想改变函数的原型以使用智能指针:
void A::foo(BPtr b);
void B::foo(APtr a);
显然,我无法转发声明APtr
或BPtr
。有效的方法是重复使用typedef
:
//B.h
class A;
typedef SmartPtr<A> APtr;
class B
{
public:
void foo(APtr a);
};
typedef SmartPtr<A> APtr;
//A.h
class B;
typedef SmartPtr<B> BPtr;
class A
{
public:
void foo(BPtr b);
};
typedef SmartPtr<A> APtr;
但我不确定这是否是正确的解决方案。有这样做的标准方法吗?我做错了什么还是危险的?
答案 0 :(得分:3)
假设您有充分理由了解这些周期性依赖关系,为什么不这样做:
// defs.h
class A;
class B;
typedef SmartPtr<A> APtr;
typedef SmartPtr<B> BPtr;
//B.h
#include "defs.h"
class B
{
public:
void foo(APtr a);
};
//A.h
#include "defs.h"
class A
{
public:
void foo(BPtr b);
};
答案 1 :(得分:2)
在公共标题中声明智能指针和类转发一次并包含它:
fwd.h:
class A;
class B;
typedef SmartPtr<A> APtr;
typedef SmartPtr<B> BPtr;
A.H:
#include "fwd.h"
struct A {
void foo(BPtr a);
};
答案 2 :(得分:2)
问题基本上归结为此代码是否正常:
#include <memory>
struct A;
typedef std::unique_ptr<A> APtr;
struct A {};
typedef std::unique_ptr<A> APtr;
...其中std :: unique_ptr可以被其他一些智能指针类替换。
typedef是一个声明,你可以在同一个声明区域中使用相同名称的声明,只要它们声明该名称完全相同,例如:< / p>
extern int i;
extern int i;
extern int i, i, i, i, i, i, i;
在他们的情况下,他们都将APtr声明为std :: unique_ptr&lt; A&gt;的别名。 A是一个声明中的不完整类型而另一个声明中的完整类型无关紧要,因为此声明不需要A的完整性(如果是,则在第一个typedef时会出现编译错误)
简而言之:它之所以有效,是因为您并未真正重新使用&#34; typedef,你只需要多次声明相同的typedef,这很好。