首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >防止C++中的类继承

防止C++中的类继承
EN

Stack Overflow用户
提问于 2010-02-02 20:57:37
回答 9查看 47.1K关注 0票数 69

最近,我的一个朋友问我如何在C++中防止类继承。他希望编译失败。

我正在考虑这个问题,找到了3个答案。不知道哪一个是最好的。

1) 私有构造函数

代码语言:javascript
复制
class CBase
{

public:

 static CBase* CreateInstance() 
 { 
  CBase* b1 = new CBase();
  return b1;
 }

private:

 CBase() { }
 CBase(CBase3) { }
 CBase& operator=(CBase&) { }


};

2) 使用 CSealed 基类、私有ctor和虚拟继承

代码语言:javascript
复制
class CSealed
{

private:

 CSealed() {
 }

 friend class CBase;
};


class CBase : virtual CSealed
{

public:

 CBase() {
 }

};

3)使用虚拟继承CSealed基类、受保护的ctor和虚拟继承的虚拟继承

代码语言:javascript
复制
class CSealed
{

protected:

 CSealed() {
 }

};

class CBase : virtual CSealed
{

public:

 CBase() {
 }

};

以上所有方法都确保了CBase类不能被进一步继承。我的问题是:

  1. 哪种方法是最好的?还有其他可用的方法吗?

除非通过病毒继承CSealed类,否则

  1. 方法2和3将无法工作。为什么会这样呢?这和vdisp ptr有关系吗??

PS:

上述程序是在MS C++编译器(Visual Studio)中编译的。参考:http://www.codeguru.com/forum/archive/index.php/t-321146.html

EN

回答 9

Stack Overflow用户

发布于 2012-09-07 21:55:09

从C++11开始,您可以将final关键字添加到类中,例如

代码语言:javascript
复制
class CBase final
{
...

我能看到的想要这样做的主要原因(以及我来寻找这个问题的原因)是将一个类标记为非子类,这样您就可以安全地使用非虚拟析构函数并完全避免使用vtable。

票数 91
EN

Stack Overflow用户

发布于 2010-02-02 21:46:52

你不能阻止继承(在C++11的final关键字之前)-你只能阻止继承类的实例化。换句话说,没有办法防止:

代码语言:javascript
复制
class A { ... };

class B : public A { ... };

你能做的最好的事情就是防止B类型的对象被实例化。在这种情况下,我建议你采纳kts的建议,记录A(或其他任何东西)不是用于继承的事实,给它一个非虚的析构函数,没有其他的虚函数,然后就到此为止。

票数 14
EN

Stack Overflow用户

发布于 2010-02-02 21:28:36

您正在经历扭曲,以防止进一步的子类化。为什么?记录该类不可扩展的事实,并使dtor成为非虚拟的。本着c的精神,如果有人真的想忽略你想要使用的方式,为什么要阻止他们呢?(我也从来没有看到final类/方法在java中的意义)。

代码语言:javascript
复制
//Note: this class is not designed to be extended. (Hence the non-virtual dtor)
struct DontExtened
{
  DontExtened();
  /*NOT VIRTUAL*/
  ~DontExtened();
  ...
};
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2184133

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档