向前声明 typedef 保护



我正在尝试转发声明一些仅在类中私下使用的变量,以限制使用此变量时必须包含的标头数量。

可悲的是,我要转发声明的类原来是一个 typedef,它是一个我无法编辑的第三方库(为了论证,我们称之为"boost::asio::strand"(

此问题 在 C++ 中转发 typedef 的声明 演示唯一的解决方案是:

  • 只需包含标题并接受这是不可能的
  • 向前声明什么将被类型定义并添加我自己的类型定义

看看第二个解决方案,有什么方法可以保护自己免受库中的 typedef 更改的影响,以便编译器在删除/重命名类时抱怨 typedef 而不是使用未定义的类型并使其不那么麻烦维护?

如果可能的话,我会尽量不依赖原始类的前向声明。我可能错过了一个案例,但我认为前向声明仅当类型以某种方式出现在方法签名中时,或者如果您的类包含以某种方式指向或引用该类型的成员,可能是间接的,则前向声明仅对纯粹的私人使用有用。

我建议转发声明类的包装器,并且仅在实际的类或typedef已知时才在实现文件中定义它。

假设您的类标头当前如下所示:

// need header because it contains UglyTypeDef:
#include <UglyHeader.h>
class MyClass {
public:
int theMethod(int a);
private:
void uglyMethod(UglyTypeDef &utd);
int someMember;
UglyTypeDef *utdp;
std::vector<UglyTypeDef *> utds;
};

在这个例子中,我们可以使用前向声明,但我们不想依赖 UglyHead 的内部。

我会像这样更改我的类:

class MyClass {
public:
int theMethod(int a);
private:
// move the private method into the implementation file   
// hide the ugly typedef
// we safely forward declare our own private wrapper
struct UglyTypeDefWrapper;
int someMember;
UglyTypeDefWrapper *utdp;
std::vector<UglyTypeDefWrapper *> utds;
};

现在,为了使这项工作,cpp 文件中的实现也必须更改:

#include "MyClass.hpp"
#include <UglyHeader.h>
struct MyClass::UglyTypeDefWrapper {
// if possible save another level of indirection 
// and store by value, otherwise use a second indirection
// by cleverly wrapping at the right level of abstraction 
// this abstraction can be free in many cases
UglyTypeDef td;
};
namespace {
// we completely hide the private method in this file as
// an implementation detail and pass it whatever it needs
// this also helps the compiler to inline it, 
// because it knows it cannot be referenced in 
// a different compilation unit
// we need to pass all members as needed
void uglyFormerMethod(int &someMember, UglyTypeDef &utd) {
someMember += utd.whatever();
}
}
int MyClass::theMethod(int a) {
utd->td.doWhatever();
uglyFormerMethod(someMember, *utd);
for(auto utdwp: utds) {
utdwp->td.doIt();
}
}

最新更新