C++;没有子类的对象? 我想知道是否有一种方法来声明C++中的对象,以防止它被子类化。是否有一种等价于在Java中声明最终对象的方法?
不,实际上不需要这样做。如果您的类没有虚拟析构函数,那么从它派生是不安全的。所以不要给它一个 您可以使用此技巧,复制自: 在C++0x中(作为扩展,在MSVC中),您实际上可以使其非常干净:C++;没有子类的对象? 我想知道是否有一种方法来声明C++中的对象,以防止它被子类化。是否有一种等价于在Java中声明最终对象的方法?,c++,C++,不,实际上不需要这样做。如果您的类没有虚拟析构函数,那么从它派生是不安全的。所以不要给它一个 您可以使用此技巧,复制自: 在C++0x中(作为扩展,在MSVC中),您实际上可以使其非常干净: template <typename T> class final { private: friend T; // C++0x, MSVC extension final() {} final(const final&) {} }; class no_deri
template <typename T>
class final
{
private:
friend T; // C++0x, MSVC extension
final() {}
final(const final&) {}
};
class no_derived :
public virtual final<no_derived> // ah, reusable
{};
模板
期末考试
{
私人:
friend T;//C++0x,MSVC扩展
最终(){}
最终(常量最终&){}
};
类别编号:
公共虚拟最终版//啊,可重用
{};
真的没有办法。您所能做的最好的事情就是将所有成员函数设置为非虚函数,并将所有成员变量设置为私有变量,这样子类化就没有任何好处了。否
最接近的是声明构造函数<代码>私下<代码>,然后提供静态工厂方法。
C++中没有直接的等价语言构造。 在技术上实现这一点的常用习惯用法是将其构造函数声明为私有。要实例化这样一个类,您需要定义一个公共静态工厂方法 这就是所谓的“制作课堂” “最后一个”或“一片叶子”。有三个 方法:一个简单的技术 方法,一种更简单的非技术性方法 方法,和一个稍微棘手 技术方法 简单的技术方法是 使类的构造函数私有 使用 创建对象。没有人能 创建派生类的对象 因为基类的构造函数 将无法访问。名为 构造器“自己可以也可以 非技术性(更简单) 方法是把一个大胖子放在一个丑陋的地方 类定义旁边的注释。 例如,评论可以说,//
如果你继承了我们的遗产,我们会解雇你
这门课是
甚至是/*期末考试*/
类{…}代码>。一些
程序员对此犹豫不决,因为它是
由人而不是由人来执行
技术,但不要在脸上敲打它
价值观:这是相当有效的
练习
一种略显棘手的技术方法
就是利用。
自,以下
保证没有具体的类可以
从类继承Fred:
ClassFred
可以访问FredBase
的ctor,
由于Fred是FredBase的朋友,
但是没有从Fred派生的类可以
访问FredBase的ctor,因此
没有人可以创建一个具体的类
源于Fred
如果你处于极度危险之中
空间受限环境(例如
作为嵌入式系统或手持设备
由于内存有限等),您应该
请注意,上述技术
可能会增加一个单词的记忆
sizeof(Fred)
。那是因为大多数
编译器实现虚拟
通过在中添加指针进行继承
派生类的对象。这是
编译器特定的;你的里程数可能会增加
变化
从C++11开始,您可以将final关键字添加到类中,例如
class CBase final
{
...
我看到想要这样做的主要原因(也是我来寻找这个问题的原因)是将一个类标记为非子类化,这样你就可以安全地使用非虚拟析构函数并完全避免vtable。如果你这样做了,如果你做了
类派生:私有基
,它还不能子类化吗?(这里是C++noob)@dreamlax,不,它没有帮助。私有继承只会进一步限制对基类成员的访问。@Péter:很高兴知道。是时候从同事那里获取我的C++书籍了。你真的想阻止一个类被子类化吗?很难真正了解一个类的未来用法。在C++中停止类被子类化是一个真正的需要。你不需要虚拟方法,在每个实例中都会节省4字节。实际上,我不打算限制子类。我只是好奇,因为我正在从java背景中学习C++,谢谢你的详细回答+1。我在标准的副本中找不到。我不知道标准,我没有读过,但是它在Bjarne Stroustrup的C++ 11中被记录了——新的ISO C++标准在OK,现在我实际上在语言标准中找到了这个用法。没有像class Base final
这样的例子,但是在第9章第一段的文本中提到了它的用法:“如果一个类用class virt说明符final
标记,并且它在一个Base子句(第10条)中显示为一个基类型说明符,那么程序的格式就不正确。”。这意味着,class Base final
不能从中派生。
class Fred;
class FredBase {
private:
friend class Fred;
FredBase() { }
};
class Fred : private virtual FredBase {
public:
...
};
class CBase final
{
...