2012-11-14 97 views
2

是否有一种方法可以在C++中显式声明基类为抽象类?显式声明抽象基类

我知道我可以在类中创建一个纯虚函数,它将隐式地声明一个类为抽象类。但是,我不想创建一个虚拟函数来定义派生类。

我也可以使受保护的构造函数,它会阻止对象的实例,但实际上并没有将类标记为抽象的。

那么,有没有办法做到这一点? (我使用C++ 11,如果添加了一个办法做到这一点,但我没有发现任何疑似右)

回答

3

可以使析构函数纯虚。因为你总是需要一个析构函数,也没有额外的心理成本:

struct Foo 
{ 
    virtual ~Foo() = 0; 
}; 

inline Foo::~Foo() { } 

(你做当然需要析构函数的实现,所以你必须提供一个离线)

你仍然可以使析构函数protected,这是遵循“make non-leaf classes abstract”规则的良好实践。

实施例:

struct Bar : Foo { }; 

// Foo f; // Error, Foo is abstract 
Bar b;  // OK 
+0

哇,那有用吗?如同在'Bar'被解构时,'Foo'解构器仍然会被调用? – Xymostech

+0

@Xymostech:自然地:-)(您可以提供* any *纯虚函数的定义。) –

+0

有趣。看起来Clang给出了一个警告:'注意:当你尝试创建一个'Foo'时,'注意:'Foo'中未实现的纯虚拟方法'〜Foo',但它很好用! – Xymostech

1

有一种方法,以显式地声明基类如C++抽象?

没有,没有。一个类只有在其中至少包含一个抽象方法时才是抽象的。如果你不想让你的基类直接实例化,那么受保护的构造函数是一个不错的选择。

1

我喜欢Kerrek的回答。这样该类不能被实例化,因此是抽象的。

但是,它仍然是没有明显的清楚,是一个抽象类,除非你通过扫描类的整个声明,看到析构函数是虚拟的。

另一个想法我已经是你可以创建使用#define单词“抽象”的预处理器定义。这样,你可以这样做以下:

abstract struct Foo {}; 

这将是没有什么不同

struct Foo {}; 

我这个看到的问题是,这并不强制类是抽象的,所以你可以使用宏来声明虚拟析构函数。喜欢的东西:

#define ABSTRACT_CLASS(class_name) \ 
    class class_name { \ 
    virtual ~class_name() = 0; // 

,然后用它像这样:

ABSTRACT_CLASS(Foo) { 
    // class declaration 
}; 

这将变成:

class foo { 
    virtual ~class_name() = 0; // { 
    // class declaration 
}; 

免责声明:我的宏可能会稍微偏离。我不确定它是否实际上将class_name和〜和()接触到变量名称。另外,我不确定自己是否会这样做,这不是最美丽的解决方案,尤其是对大括号进行评论,因为如果将其放在下一行上,这样做不起作用。但你问过你如何标记抽象的东西,然后把它交给你!