C++ 正向声明typedef保护

C++ 正向声明typedef保护,c++,c++11,forward-declaration,C++,C++11,Forward Declaration,我试图前向声明一些仅在类中私自使用的变量,以限制使用此变量时必须包含的头数 遗憾的是,我想要向前声明的类已经变成了一个typedef,它是一个我无法编辑的第三方库(为了便于讨论,我们称它为“boost::asio::strand”) 这个问题表明,唯一的解决办法是: 只需包含标题并接受这是不可能的 转发声明将要定义的类型并添加我自己的类型定义 看看第二个解决方案,有什么方法可以保护我自己不受库中typedef更改的影响,这样当类被删除/重命名时,编译器会抱怨typedef而不是使用未定义的类

我试图前向声明一些仅在类中私自使用的变量,以限制使用此变量时必须包含的头数

遗憾的是,我想要向前声明的类已经变成了一个typedef,它是一个我无法编辑的第三方库(为了便于讨论,我们称它为“boost::asio::strand”)

这个问题表明,唯一的解决办法是:

  • 只需包含标题并接受这是不可能的
  • 转发声明将要定义的类型并添加我自己的类型定义

看看第二个解决方案,有什么方法可以保护我自己不受库中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;
};
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;
};
//需要标头,因为它包含UglyTypeDef:
#包括
类MyClass{
公众:
int方法(INTA);
私人:
无效uglyMethod(UglyTypeDef和utd);
内部成员;
UglyTypeDef*utdp;
std::向量utds;
};
在本例中,我们可以使用转发声明,但我们不希望依赖UglyHeader的内部

我会这样改变我的班级:

// 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;
};
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;
};
class-MyClass{
公众:
int方法(INTA);
私人:
//将私有方法移动到实现文件中
//隐藏丑陋的字体
//我们安全地转发声明我们自己的私有包装器
结构UglyTypeDefWrapper;
内部成员;
UglyTypeDefWrapper*utdp;
std::向量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();
  }
}
#包括“MyClass.hpp”
#包括
结构MyClass::UglyTypeDefWrapper{
//如果可能,请保存另一级别的间接寻址
//并按值存储,否则使用第二个间接寻址
//通过在正确的抽象层次上巧妙地包装
//这种抽象在许多情况下是免费的
丑陋的;
};
名称空间{
//我们在这个文件中完全隐藏私有方法,如下所示
//一个实现细节,并根据需要传递它
//这也有助于编译器内联它,
//因为它知道它不能在中引用
//不同的编译单元
//我们需要根据需要通过所有成员
void-uglyFormerMethod(int&someMember,UglyTypeDef&utd){
someMember+=utd.whatever();
}
}
int MyClass::theMethod(int a){
utd->td.doWhatever();
丑陋的方式(某些成员,*utd);
用于(自动utdwp:utds){
utdwp->td.doIt();
}
}

使用pimpl?͏͏͏͏͏͏͏͏͏͏@wally虽然它确实有效,而且肯定不需要包含对象,但这不是我想要做的,因为它意味着,而不是拥有一个(例如)私有代码> STD::向量我现在需要一个代码> pIMPL*/COD>,它包含了<代码> STD::vector < /代码>。C+C++的概念是,你不为你不使用的东西付出代价,而且这个额外的对象的代价是我不需要的。在命名空间内是第三方库吗?@是的。为了便于讨论,我们可以将这个名称空间称为“boost”。你知道,在尝试回答之后,我认为这里没有足够的信息。为什么你只需要一份远期申报单?您是否计划在公共界面中使用它?在这种情况下,您的用户仍将包括标题。你只私下使用吗?那么,为什么您只能使用一个转发声明呢?