使用两个相同的 typedef 不好吗,如何避免它?

Is using two identical typedefs bad and how to avoid it?

提问人:Luchian Grigore 提问时间:1/27/2012 最后编辑:Luchian Grigore 更新时间:1/27/2012 访问量:855

问:

由于存在循环依赖关系,因此对某些类使用正向声明:

//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);

显然,我不能转发声明或.有效的方法是重用:APtrBPtrtypedef

//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;

但我不确定这是否是正确的解决方案。有没有标准的方法可以做到这一点?我做错了还是危险?

C++ typedef 智能指针 forward-declaration

评论


答:

3赞 Samuel Harmer 1/27/2012 #1

假设你有充分的理由支持这些周期性依赖关系,为什么不这样做呢:

// 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);
};

评论

0赞 Luchian Grigore 1/27/2012
我确实想到了这一点,但我认为存在另一种方式。
0赞 Samuel Harmer 1/27/2012
你可能是对的,其他方式确实存在。但最好的解决方案往往是最简单的。
2赞 thiton 1/27/2012 #2

在公共标头中声明一次智能指针和类转发,并包含它:

fwd.h:

class A;
class B;
typedef SmartPtr<A> APtr;
typedef SmartPtr<B> BPtr;

答:

#include "fwd.h"

struct A {
    void foo(BPtr a);
};
2赞 user450018 1/27/2012 #3

问题基本上可以归结为这段代码是否正常:

#include <memory>

struct A;

typedef std::unique_ptr<A> APtr;

struct A {};

typedef std::unique_ptr<A> APtr;

...其中 std::unique_ptr 可以替换为其他一些智能指针类。

typedef 是一个声明,您可以在同一个声明性区域中拥有任意数量的相同名称的声明,只要它们声明该名称完全相同,例如:

extern int i;
extern int i;
extern int i, i, i, i, i, i, i;

在您的例子中,它们会 - 它们都声明 APtr 为 std::unique_ptr<A> 的别名。A 在一个声明中是不完整的类型,而在另一个声明中是完整的类型并不重要,因为此声明不需要 A 的完整性(如果是的话,您将在第一个 typedef 时出现编译错误)。

简而言之:它之所以有效,是因为您并没有真正“重用”typedef,而只是多次声明相同的typedef,这很好。

评论

0赞 Luchian Grigore 1/27/2012
有趣的一点,和+1。但我更喜欢其他答案提出的解决方案。它看起来更清晰。