使用C++接口的最佳方式

Set*_*eth 6 c++ interface

我有一个类似于的接口类:

class IInterface
{
public:

    virtual ~IInterface() {}

    virtual methodA() = 0;

    virtual methodB() = 0;

};
Run Code Online (Sandbox Code Playgroud)

然后我实现了界面:

class AImplementation : public IInterface
{
    // etc... implementation here
}
Run Code Online (Sandbox Code Playgroud)

当我在应用程序中使用接口时,最好创建具体类AImplementation的实例.例如.

int main()
{
    AImplementation* ai = new AIImplementation();
}
Run Code Online (Sandbox Code Playgroud)

或者最好在接口中放置工厂"创建"成员函数,如下所示:

class IInterface
{
public:

    virtual ~IInterface() {}

    static std::tr1::shared_ptr<IInterface> create(); // implementation in .cpp
    virtual methodA() = 0;

    virtual methodB() = 0;

};
Run Code Online (Sandbox Code Playgroud)

然后我就可以在main中使用这样的接口:

int main()
{
    std::tr1::shared_ptr<IInterface> test(IInterface::create());
}
Run Code Online (Sandbox Code Playgroud)

第一种选择似乎是常见的做法(不是说它的权利).但是,第二个选项来自"Effective C++".

Ash*_*Ash 9

使用接口的最常见原因之一是,您可以"针对抽象编程"而不是具体实现.

这样做的最大好处是它允许更改代码的各个部分,同时最大限度地减少剩余代码的更改.

因此,虽然我们不知道您正在构建的完整背景,但我会选择接口/工厂方法.

说到这一点,在较小的应用程序或原型中,我经常从具体类开始,直到我感觉到界面在哪里/是否需要.接口可以引入一个间接级别,这对于您正在构建的应用程序规模可能不是必需的.

因此,在较小的应用程序中,我发现我实际上并不需要自己的自定义界面.像许多事情一样,您需要权衡特定于您的情况的成本和收益.


Mic*_*yan 5

还有一个你没有提到的替代方案:

int main(int argc, char* argv[])
{
   //...
   boost::shared_ptr<IInterface> test(new AImplementation);
   //...
   return 0;
}

换句话说,可以使用智能指针而不使用静态"创建"功能.我更喜欢这种方法,因为"创建"功能只增加了代码膨胀,而智能指针的好处是显而易见的.

  • 如果应该隐藏实现,将动态加载,依赖于平台(例如AWindowsImplementation,AMacImplementation,ALinuxImplementation),或者取决于许多配置参数,那么你应该创建一个工厂.但是,恕我直言,你应该使用一个单独的工厂类. (2认同)