2013-03-27 120 views
1

我在某处读过抽象基类的构造函数应该被保护吗?为什么这是一个推荐的做法,如果不受保护,这些如何被滥用?受保护的抽象基类的构造函数和析构函数?

+5

对我没有任何意义。我认为这取决于你在哪里阅读过这个“某处”。 – 2013-03-27 14:09:38

+2

我个人认为它记录了正确的用法。 – 2013-03-27 14:13:01

+3

在C++中,抽象类需要具有纯虚拟方法。这可以防止它们被初始化。然而,如果你有一个没有纯虚方法的类,但你仍然想阻止它在继承之外使用,那么上面的方法就可以做到这一点。但我不会称之为“抽象基类”。 – andre 2013-03-27 14:21:12

回答

1

如果您认为这是建议的做法,您应该询问实际推荐的人。 C++中的抽象类是一个至少有一个纯虚函数的类。编译器不会让你创建这样的类的实例,并帮助它与受保护的构造函数没有多大意义。这是基于你提供的信息,作者可能有理由,但你可能会误解这个概念。

+0

请检查我的帖子。我认为问题在于命名。在C++方面的“抽象”和在面向对象设计方面的“抽象”。在C++中使用纯虚方法,你必须让你的类“虚拟化”,也就是说它必须包含一个“虚拟方法”(即纯粹的方法),所以它增加了一个vtable和blahblah ..因此,使OO意义上的班级抽象 - 这是笨拙的。通过将ctor标记为受保护的,您不需要虚拟方法,也不需要vtable。这样的班级更轻,但仍不能自行实例化。 – quetzalcoatl 2013-03-27 14:27:46

+0

您可以使用受保护的构造函数yes。这与问题无关。 – Slava 2013-03-27 14:41:11

1

我认为该建议的重点是假设,核心可读性和维护。

在C++中,如果你在你的班上有任何纯虚方法,那么它被认为是抽象和自动非实例。没有需要保护的电源/ dtors。有一些功夫的方法可以创造类似于抽象类的东西,但是如果你知道如何去做,那就是你的范例问题:)

但是,术语“抽象”也可以是仅仅被认为是该课程目的的一般描述。如果要求,那么每个这样的“抽象”类只需要一个纯粹的虚拟方法就会很奇怪。如果它对这个班没有任何意义呢?你必须引入一个完全不相关的p-v方法来将该类标记为“abstract”。通过将ctors标记为受保护的,可以确保您的class-without-pure-virtuals也不是可自由创建的。

对保养的影响也很小:假设你有一个绝对抽象的类,有一些虚拟方法和一个纯虚拟。你公开了ctors/dtors。然后,在每半年你修补/升级/修改类,并将纯虚拟变成不是“纯”的,并且有一些默认实现。哎呦。现在你的课是可以创作的。 [我故意忽略纯虚拟可以有实现为了人为的例子]。

当然,完全另一个问题是 - 有什么好处是这样的抽象基础无虚拟方法?我无法找到使用的例子除了构建基于标志半多态性:

struct Base { protected: base(){} public: int type; } 
struct Derived1:Base { derived1(){type=1;} int shoesize; string codename; } 
struct Derived2:Base { derived2(){type=2;} string name, family; } 

在那里你可以通过碱基指针传递derived1/2和由“类型”标志检测它们的类型,和后来手动施放它们..没有RTTI,没有vtable,很轻的物体。有时你需要它。

因此,在保护它们方面有一些好处,但是这个收益是......好,很小。

+0

你能描述一下创建抽象类没有任何虚拟方法的目的吗? – Slava 2013-03-27 14:27:25

+0

@Slava,考虑一下关于[virtuality](http://www.gotw.ca/publications/mill18.htm)的文章。一个充满模板方法的类,但所有虚拟类都提供了一个默认实现。现在,更有意义的是:随机选择一种方法并使其成为“纯虚拟”,或将ctor声明为受保护的? – StoryTeller 2013-03-27 14:32:46

+0

@Slava - 非常好的问题。我只是使用抽象非虚拟基础的代码示例更新我的文章。它是不使用RTTI的非动态类型识别。有时候vtables价格昂贵,或者有时候你的平台......根本不支持RTTI。请记住,C++也是高度多范型和高度多平台的。 – quetzalcoatl 2013-03-27 14:36:37