简体   繁体   English

分离接口和C ++实现

[英]Separating Interface and Implementation in C++

If I have a simple header file: 如果我有一个简单的头文件:

namespace aNamespace {
    class AClass {
        public:
        AClass();
        ~AClass();

        bool Init();
        void Shutdown();
    };
}

What is the 'correct' way to implement this class in the corresponding CPP file? 在相应的CPP文件中实现此类的“正确”方法是什么? I can see two options: 我可以看到两个选项:

Option A 选项A

namespace aNamespace {
    class AClass {
        public:
        AClass() { ... }
        ~AClass() { ... }

        bool Init() { ... }
        void Shutdown() { ... }
    };
}

Option B 选项B

namespace aNamespace {
    AClass::AClass() { ... }
    AClass::~AClass() { ... }

    bool AClass::Init() { ... }
    void AClass::Shutdown() { ... }
}

The problem I see with Option B is that it's hard to add implementation-specific members to AClass - eg what if the implementation requires a std::wstring or so as a storage variable; 我在选项B中看到的问题是,很难向AClass添加特定于实现的成员-例如,如果实现需要std::wstring或类似的存储变量,该怎么AClass but that variable isn't defined in the header file? 但是该变量没有在头文件中定义吗?

The reason I'm asking this is because I may wish to have multiple implementations of AClass , and select which one to link according to some external variable (eg the target platform or architecture). 我之所以这样问,是因为我可能希望有AClass多个实现,并根据某个外部变量(例如目标平台或体系结构)选择要链接的那个。

Another option would be to actually make name of each implementation platform specific and have a simple typedef switch in header to control which one is chosen based on target/architecture: 另一个选择是实际指定每个实现平台的名称,并在标头中使用简单的typedef开关来控制根据目标/体系结构选择哪个:

#ifdef target1
typedef AClass Target1ClassImplementation;
#elif  defined target2
typedef AClass Target2ClassImplementation;
#else
#error AClass is not implemented for current target
#endif

If desired, common interface can be encapsulated in a base class implementations derive from. 如果需要,可以将通用接口封装在派生的基础类中。 It is less error prone since is more explicit in sense which implementation is for what target, while allows using AClass regardlesss of a platform target outside of header. 由于从某种意义上说哪个实现是针对哪个目标的,在更明确的意义上,它更不容易出错,而无论标头之外的平台目标如何,都允许使用AClass。

B is much better in most cases: B在大多数情况下要好得多:

Advantages: 好处:

  • Hide implementation details. 隐藏实施细节。
  • Less #includes in header files (less exposed dependencies!): 头文件中的#include更少(暴露的依赖项更少!):
    • Faster builds 更快的构建
    • 2 classes can call each other's functions. 2个类可以调用彼此的函数。 Very tricky to do if both are in headers. 如果两者都在标头中,则非常棘手。
    • Changes to implementation do affect other classes (build time). 对实现的更改确实会影响其他类(构建时间)。

Disadvantages: - Functions in CPP file do not inline in other modules (across library boundaries) 缺点:-CPP文件中的函数未在其他模块中内联(跨库边界)

Optimal: Decide per function which is best. 最佳:确定每个功能的最佳选择。 Short one liners to the header and longer ones to the cpp(s). 将一根短衬管连接到割台,将一根长衬管连接到cpp。 You can have more than 1 source file for the class implementation. 您可以为该类实现使用多个源文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM