如何设置表示接口的类?这只是一个抽象基类吗?
当前回答
除了上面写的内容,还有一点补充:
首先,确保析构函数也是纯虚拟的
第二,您可能希望在执行时实际上继承(而不是正常继承),只是为了获得好的度量。
其他回答
下面是c++标准中抽象类的定义
第4687页
13.4.2
抽象类是只能用作其他类的基类的类;没有抽象对象类只能作为派生类的子对象来创建。如果类至少具有一个纯虚拟函数。
使用纯虚拟方法创建类。通过创建另一个重写这些虚拟方法的类来使用该接口。
纯虚拟方法是定义为虚拟并分配给0的类方法。
class IDemo
{
public:
virtual ~IDemo() {}
virtual void OverrideMe() = 0;
};
class Child : public IDemo
{
public:
virtual void OverrideMe()
{
// do stuff
}
};
除了上面写的内容,还有一点补充:
首先,确保析构函数也是纯虚拟的
第二,您可能希望在执行时实际上继承(而不是正常继承),只是为了获得好的度量。
C++中没有“接口”本身的概念。AFAIK,接口首先在Java中引入,以解决缺少多重继承的问题。事实证明,这个概念非常有用,在C++中使用抽象基类也可以达到同样的效果。
抽象基类是一个类,其中至少一个成员函数(Java语言中的方法)是使用以下语法声明的纯虚拟函数:
class A
{
virtual void foo() = 0;
};
抽象基类不能实例化,即不能声明类A的对象。只能从A派生类,但任何不提供foo()实现的派生类也将是抽象的。为了停止抽象,派生类必须为其继承的所有纯虚拟函数提供实现。
请注意,抽象基类可以不仅仅是一个接口,因为它可以包含非纯虚拟的数据成员和成员函数。接口的等价物是一个抽象基类,没有任何数据成员,只包含纯虚拟函数。
而且,正如MarkRansom所指出的,抽象基类应该像任何基类一样提供虚拟析构函数。
考虑这一点的一个好方法是继承接口而不是继承实现。在C++中,您可以同时继承接口和实现(公共继承),也可以只继承实现(私有继承)。在Java中,您可以选择只继承接口,而不继承实现。
如果您只需要接口的静态绑定(没有虚拟的,没有接口类型本身的实例,接口仅作为指南):
#include <iostream>
#include <string>
// Static binding interface
// Notice: instantiation of this interface should be usefuless and forbidden.
class IBase {
protected:
IBase() = default;
~IBase() = default;
public:
// Methods that must be implemented by the derived class
void behaviorA();
void behaviorB();
void behaviorC() {
std::cout << "This is an interface default implementation of bC().\n";
};
};
class CCom : public IBase {
std::string name_;
public:
void behaviorA() { std::cout << "CCom bA called.\n"; };
};
class CDept : public IBase {
int ele_;
public:
void behaviorB() { std::cout << "CDept bB called.\n"; };
void behaviorC() {
// Overwrite the interface default implementation
std::cout << "CDept bC called.\n";
IBase::behaviorC();
};
};
int main(void) {
// Forbid the instantiation of the interface type itself.
// GCC error: ‘constexpr IBase::IBase()’ is protected within this context
// IBase o;
CCom acom;
// If you want to use these interface methods, you need to implement them in
// your derived class. This is controled by the interface definition.
acom.behaviorA();
// ld: undefined reference to `IBase::behaviorB()'
// acom.behaviorB();
acom.behaviorC();
CDept adept;
// adept.behaviorA();
adept.behaviorB();
adept.behaviorC();
// adept.IBase::behaviorC();
}