在 C++ 中,“对象”和“实例”几乎可以互换使用。
有一个通用的编程设计模式class 和instance。 class 保存了 class 中所有 instances 的信息。
在 C++ 中,当您声明 class 或 struct 时,编译器生成的代码描述了您如何创建该 class 的 instance、数据布局是什么,并提供一些可以使用的方法与instance 进行交互(直至并包括销毁)。
virtual 方法和继承看似将一些方法和布局移动到实例中:但数量非常有限。相反,每个实例都持有指向virtual 类数据的指针。在某些语言中,您可以执行诸如在运行时替换实例的各个方法之类的操作:但在 C++ 中则不行。
当您创建class 或struct 的实例时,它可以通过堆栈上的自动命名变量(如Foo f;)、匿名自动命名变量(如some_function( Foo(17,22) ))、实例在免费商店(如new Foo(17, 22)),或通过placement-new(这是std::vector 和std::make_shared 创建实例的方式)。
令人困惑的是,C++ 中有一个单独的并行 class-instance 模式——class template-class。 class template 是class,实例化是实例。 template 参数和特化说明如何在编译时“构造”classes。 class templates 上的模式匹配提供了数量有限的与实例无关的属性(模式中的“类属性”)。 (可以说函数模板函数是该模式的另一个实例)。
如果您查看C++1y proposal for concepts lite,您会发现对象和实例在 C++ 中的含义可能不同。
int x = 0;
int& foo = x;
int* bar = &x;
x 既是对象又是 int 类型的实例。
foo 是int& 类型的一个实例,但是调用foo 一个对象可能是错误的!它是一个引用——一个别名,或者某个对象的不同名称(在本例中为 x)。
bar 是指向int 的指针,它是int* 类型的实例,将其称为对象可能是正确的。
这是一个有用的区别:如果类型是引用类型,则类型不必表示对象类型。对象类型在许多重要方面的行为与引用类型不同。
现在,某些类型具有“引用语义”,因为它们在许多方面表现得像引用,但实际上是classes。这种类型的实例是否更好地称为引用或对象?在可怕的情况下,某些实例同时具有引用和对象语义:这通常是一个不好的迹象。
通过 3.9 [Types] 中的latest standard,我们拥有 C++ 中的类型。他们描述了对象类型是什么:
类型描述对象 (1.8)、引用 (8.3.2) 或函数 (8.3.5)
和
对象类型是(可能是 cv 限定的)类型,它不是函数类型、引用类型,也不是 void 类型。
因此,将函数类型或引用类型的“实例”称为“对象”似乎是不正确的。请注意,访问函数或引用实例的“表示”基本上是不可能的:引用别名为它们所引用的对象,并且使用函数的名称会衰减到一个指向函数的指针(和指向函数的指针基本上是不透明的句柄,可让您调用它们)。
因此可以说函数不是实例,引用也不是实例。
另一方面,我们确实讨论了classtemplates 和函数templates 的实例化。 14.7 是“模板实例化和特化”,实例化点(template)都是标准中的正式术语。