我在某处读过抽象基类的构造函数应该被保护吗?为什么这是一个推荐的做法,如果不受保护,这些如何被滥用?受保护的抽象基类的构造函数和析构函数?
回答
如果您认为这是建议的做法,您应该询问实际推荐的人。 C++中的抽象类是一个至少有一个纯虚函数的类。编译器不会让你创建这样的类的实例,并帮助它与受保护的构造函数没有多大意义。这是基于你提供的信息,作者可能有理由,但你可能会误解这个概念。
请检查我的帖子。我认为问题在于命名。在C++方面的“抽象”和在面向对象设计方面的“抽象”。在C++中使用纯虚方法,你必须让你的类“虚拟化”,也就是说它必须包含一个“虚拟方法”(即纯粹的方法),所以它增加了一个vtable和blahblah ..因此,使OO意义上的班级抽象 - 这是笨拙的。通过将ctor标记为受保护的,您不需要虚拟方法,也不需要vtable。这样的班级更轻,但仍不能自行实例化。 – quetzalcoatl 2013-03-27 14:27:46
您可以使用受保护的构造函数yes。这与问题无关。 – Slava 2013-03-27 14:41:11
我认为该建议的重点是假设,核心可读性和维护。
在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,很轻的物体。有时你需要它。
因此,在保护它们方面有一些好处,但是这个收益是......好,很小。
你能描述一下创建抽象类没有任何虚拟方法的目的吗? – Slava 2013-03-27 14:27:25
@Slava,考虑一下关于[virtuality](http://www.gotw.ca/publications/mill18.htm)的文章。一个充满模板方法的类,但所有虚拟类都提供了一个默认实现。现在,更有意义的是:随机选择一种方法并使其成为“纯虚拟”,或将ctor声明为受保护的? – StoryTeller 2013-03-27 14:32:46
@Slava - 非常好的问题。我只是使用抽象非虚拟基础的代码示例更新我的文章。它是不使用RTTI的非动态类型识别。有时候vtables价格昂贵,或者有时候你的平台......根本不支持RTTI。请记住,C++也是高度多范型和高度多平台的。 – quetzalcoatl 2013-03-27 14:36:37
- 1. 使用make_shared与受保护的构造函数+抽象接口
- 2. C++抽象基类的构造函数/析构函数 - 一般正确性
- 3. 未解析的外部(抽象类的构造函数/析构函数)
- 4. 抽象类和构造函数
- 5. 抽象类和构造函数
- 6. Java:抽象类构造函数和this()
- 7. 抽象类构造函数和普通类构造函数的区别?
- 8. 的Java抽象类的构造函数
- 9. 抽象类中的构造函数?
- 10. 抽象类的构造函数
- 11. 抽象类中的构造函数?
- 12. 构造函数和析构函数 - C++
- 13. 抽象类,复制构造函数
- 14. C中的继承树和受保护的构造函数#
- 15. 受保护的斯卡拉内部类构造函数
- 16. 构造函数中的调用基构造函数和其他构造函数
- 17. 使用受保护的析构函数删除对象
- 18. DataRow和受保护的内部构造函数
- 19. Castle.Windsor:具有空的受保护构造函数的解析类型
- 20. 定义抽象基类的默认构造函数
- 21. 确定抽象基类的构造函数是否为noexcept?
- 22. 抽象参数构造函数
- 23. scala类的构造函数和抽象类型
- 24. Excel VBA对象构造函数和析构函数
- 25. 有关抽象类与私人,公共和受保护的构造函数的一些问题
- 26. 关于受保护的构造函数的查询
- 27. Move构造函数调用基类移动构造函数
- 28. 使用反射从抽象基类访问构造函数
- 29. 字符串类的构造函数和复制构造函数
- 30. 受保护构造函数的实际用途是什么?
对我没有任何意义。我认为这取决于你在哪里阅读过这个“某处”。 – 2013-03-27 14:09:38
我个人认为它记录了正确的用法。 – 2013-03-27 14:13:01
在C++中,抽象类需要具有纯虚拟方法。这可以防止它们被初始化。然而,如果你有一个没有纯虚方法的类,但你仍然想阻止它在继承之外使用,那么上面的方法就可以做到这一点。但我不会称之为“抽象基类”。 – andre 2013-03-27 14:21:12