我遇到了这篇文章,其中术语“单态”在 C++ 语言的上下文中使用,从 1997 年开始的赋值运算符剖析。这个术语似乎很少在其他地方使用,这意味着它可能在 C++ 中浮动在 90 年代循环,但没有获得太大的牵引力,不再使用。文章指出:
问题如下:
考虑以下类定义:
class TFoo : public TSuperFoo {
TBar* fBar1;
TBar* fBar2;
// various method definitions go here...
}
你有一个类 ,TFoo
它是一个类 的后代TSuperFoo
,它有两个数据成员,它们都是指向类对象的指针TBar
。出于本练习的目的,将两个指针都考虑为具有拥有语义和TBar
单态类。为这个类编写赋值运算符。
查看各种字典定义,最常见的词根“morphic”被定义为“具有特定形式或形状”,然后是一些指示它通常与某些前缀一起使用,例如 poly(多态)或 homo(同态)。
前缀“mono”最常被定义为“single”或“one”或“lone”,通常与一些后缀一起使用,例如“plane”(单翼或单翼飞机)或“rail”(单轨或单轨或追踪)。
在这种情况下以及似乎是问题的情况下,“单态”(单态)被用作“多态”(多态)的对立面。单态类是不用作任何其他类的基类也不从另一个类派生的类。
单态类的更严格定义是该类还必须仅使用单态类或内置数据类型。单态类不得包含任何多态类作为其定义或行为的一部分。
这确实提出了一个严格的单态类是否可以包含模板化变量或方法的问题。我的第一个直觉是,只要模板创建一个单态类就可以了。换句话说,如果编译器正在为您编写一个单态类,那么它就像是 Sally 在下排隔间中编写它一样。
那么也许严格的定义应该排除运行时多态性?
因此,通过第一个不太严格的单态类定义,Foo
问题中的类似乎是单态的,因为它不是从任何其他类派生的,也没有virtual
析构函数,暗示它不打算用于派生另一个类类,也没有任何virtual
方法。
然而,它确实std::cout
在该print()
方法中使用,并且std::cout
绝对是多态的。所以也许更准确地说这是一个半单态类,因为它使用了一个多态类?
看起来单态类是独立的。但是,我们如何编写一个类,使其独立,编译器将标记任何从该类派生另一个类的尝试。
C++ 允许一个类通过从现有类派生一个新类成为其他类的超类。关于什么是可能的,多态性如何成功工作,有时有许多非常复杂的规则,但是最终将final
关键字(C++11)与一个类一起使用是唯一合理的方法来创建一个类,另一个类无法导出。
虽然浏览了一下,我发现这篇文章Simulating final class in C++,它提供了一个使用private
构造函数和virtual
继承的方法。
/* A program without any compilation error to demonstrate that instances of
the Final class can be created */
#include<iostream>
using namespace std;
class Final;
class MakeFinal
{
private:
MakeFinal() { cout << "MakeFinal constructor" << endl; }
friend class Final;
};
class Final : virtual MakeFinal
{
public:
Final() { cout << "Final constructor" << endl; }
};
int main(int argc, char *argv[])
{
Final f;
return 0;
}