0

回到 C++ 的世界,并尝试接口。我可以找到很多在线示例,但其中 99% 都是微不足道的“一体式文件”。

接口可以分为 3 种基本类型 - 接口,其中 (all|some|zero) 函数必须在具体子类中被覆盖(在 c++ 中,all|some|zero 纯虚函数)。

是否可以在单个头文件中实现这 3 个中的任何一个?(没有 .cpp 双胞胎)为什么/为什么不呢?如何?如果没有,我对 .h/.cpp 对有哪些选择?

我见过的一些选项是:虚拟析构函数,受保护的析构函数,内联析构函数,带有实现的纯虚拟析构函数,......我的头在旋转!

编辑:意味着纯虚拟,而不是虚拟虚空

4

3 回答 3

1
  • 如果你让你的接口纯虚拟,如果你忘记在你的具体类中实现一个方法,编译器会报错。
  • 如果有些方法具有一些合理的默认实现,您可以提供它,但这只是一种方便。
  • 如果将析构函数设为虚拟,则可以delete通过其接口指针来获取对象,而不需要具体的对象指针。

Herb Sutter 对接口有一些有趣的想法,这些想法与我们大多数人实现接口的方式直接不一致:http ://www.gotw.ca/publications/mill18.htm

于 2012-08-09T20:16:01.530 回答
0

阅读这篇很棒的互联网智慧: http: //www.parashift.com/c++-faq-lite/dtors.html

1) 你永远不需要 .cpp 文件,你可以在 .h 中编写所有程序,但这样做是很糟糕的风格,并且不可避免地会减慢你的编译速度。

MyClass : public MyInterface {
    public:
    virtual void myFunction() {
        // override and implemenht
    }
};

2) 继承类时,您不必担心将析构函数声明为虚拟,但您需要确保要继承的类具有虚拟析构函数。否则你可能会面临内存泄漏。据我所知,这对于只有纯虚函数的接口类是没有必要的。

内联的析构函数对您没有任何影响。

将析构函数声明为 void 应该会给您一个编译器错误:)。

编辑: 关于 3 种类型的界面,我感觉你有点困惑,这妨碍了你的谷歌搜索。

接口通常是一个没有定义函数的类,您必须继承并实现所有函数。

具有某些功能但仍具有一些纯虚的类通常称为抽象类。

当必须重写“零”函数时,这既不是接口也不是抽象类,它只是一个普通的旧类,您可以继承并做任何事情。

查看 C++ 常见问题解答。

于 2012-08-09T20:10:38.673 回答
0

调用所有函数必须被具体子类覆盖的接口interface

调用某些函数必须被具体子类覆盖的接口abstract class

调用必须由具体子类覆盖零函数的接口class

您可以在头文件中实现虚拟成员函数。但是它们不会内联,因为它们必须有地址才能放入虚拟表中。

......我的头在旋转!

为了让它旋转得更多,您还可以拥有pure virtual destructor. 当您想要拥有抽象类但没有真正有用的方法来放置纯虚拟时,这是有用的技巧:

class A
{
public:
    virtual ~A() = 0;
};

A::~A() {}

class B : public A
{
public:
    ~B() {}
};

A类实现了析构函数,但还是不能直接实例化,因为它是接口。然而,在销毁B编译器时,必须遵守协议并调用 ~A()。这就是为什么你必须实施它

于 2012-08-09T20:19:22.950 回答