繁体   English   中英

分离接口和C ++实现

[英]Separating Interface and Implementation in C++

如果我有一个简单的头文件:

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

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

在相应的CPP文件中实现此类的“正确”方法是什么? 我可以看到两个选项:

选项A

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

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

选项B

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

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

我在选项B中看到的问题是,很难向AClass添加特定于实现的成员-例如,如果实现需要std::wstring或类似的存储变量,该怎么AClass 但是该变量没有在头文件中定义吗?

我之所以这样问,是因为我可能希望有AClass多个实现,并根据某个外部变量(例如目标平台或体系结构)选择要链接的那个。

另一个选择是实际指定每个实现平台的名称,并在标头中使用简单的typedef开关来控制根据目标/体系结构选择哪个:

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

如果需要,可以将通用接口封装在派生的基础类中。 由于从某种意义上说哪个实现是针对哪个目标的,在更明确的意义上,它更不容易出错,而无论标头之外的平台目标如何,都允许使用AClass。

B在大多数情况下要好得多:

好处:

  • 隐藏实施细节。
  • 头文件中的#include更少(暴露的依赖项更少!):
    • 更快的构建
    • 2个类可以调用彼此的函数。 如果两者都在标头中,则非常棘手。
    • 对实现的更改确实会影响其他类(构建时间)。

缺点:-CPP文件中的函数未在其他模块中内联(跨库边界)

最佳:确定每个功能的最佳选择。 将一根短衬管连接到割台,将一根长衬管连接到cpp。 您可以为该类实现使用多个源文件。

暂无
暂无

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

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