c++ - 选择替代实现和前向声明

标签 c++ forward-declaration clang++

我有一个库,其中有一个供下游客户端代码使用的特定类。此类派生自一组基类。例如,

A.h :-
namespace my_lib {
  class A : public BaseClass1 {
  };
}

现在,我想提供一个派生自另一组基类的 A 类的替代实现,并允许客户端选择编译/链接哪个基类。因此,我想要某种方式在同一个共享/静态库中发布这两个实现。

例如,

NewA.h :-
namespace my_lib {
  class newA : public BaseClass2 {
  };
}

我尝试使用 typedef,但这会导致前向声明出现问题。例如,

ClientA.h :-
namespace my_lib {
  #ifdef LEGACY_A
    typedef A ClientA;
  #else
    typedef NewA ClientA;
  #endif
}

因此,客户端将只使用类名 my_lib::ClientA。但是,如果客户端有前向声明,这会导致下游出现问题。

例如,

clientclass.h :-
namespace my_lib {
  class ClientA;
  class clientClass {
    clientClass(ClientA* a);
  };
}

这给出了一个错误:-

clientclass.h: error: definition of type 'ClientA' conflicts with typedef of the same name
class ClientA;
      ^
ClientA.h: note: 'ClientA' declared here
typedef my_lib::newA ClientA;

另一方面,如果我使用 namespace 和 using 指令,我又会遇到麻烦:-

A.h:-
namespace my_lib_legacy {
  class A : public BaseClass1 {
  };
}
newA.h :-
namespace my_lib_new {
  class A : public BaseClass2 {
  };
}
ClientA.h :-
namespace my_lib {
  #ifdef LEGACY_A
    using my_lib_legacy::A;
  #else
    using my_lib_new::A;
  #endif
}
clientclass.h :-
namespace my_lib {
  class A;
  class clientClass {
    clientClass(A* a);
  };
}

但是,这会引发歧义错误,如下所示:-

clientclass.h: error: reference to 'A' is ambiguous
  explicit clientClass(A* a)
                       ^
clientclass.h: note: candidate found by name lookup is 'my_lib::A'
class A;
      ^
ClientA.h: note: candidate found by name lookup is 'my_lib::A'
using my_lib_legacy::A;

最佳答案

我只想告诉您的客户,不允许他们转发声明您的库组件并使用 typedef 方法。这对我来说似乎非常合理。

由于您的库不会一直更改,并且它已经在内部处理任何与依赖相关的前向声明,因此它们没有理由需要通过从您的库中进行前向声明来依赖特定的内部实现。

如果您愿意,也可以选择提供 <your_lib_name_fwd>转发的 header 适本地声明了关键组件,但我认为这不是强制性的。这有先例,例如标准库的 <iosfwd>

关于c++ - 选择替代实现和前向声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29612387/

相关文章:

c++ - MySQL C++ 连接器 : error adding symbols: File format not recognized

c++ - 如何痛饮省略前向声明

c++ - integral_constant 和模板参数推导

c++ - P0522R0如何破码?

c++ - 跨不同功能使用 Goto 功能

C++ 如何迭代到动态数组的末尾?

c++ - friend 类需要包含或转发声明 C++?

c++ - 为什么编译器要为这个循环的每次迭代写入一个成员变量到内存中?

c++ - 将中等数量的 T* static_casting 为 void* 时发生访问冲突

c++ - 如何在同一个类中转发声明一个函数?