类怎么不是C++中的对象

How are classes not objects in C++?

本文关键字:对象 C++      更新时间:2023-10-16

我正在阅读"设计模式:可重用面向对象软件的元素"(特别是关于原型设计模式的章节),它指出......

"原型对于静态语言特别有用,例如C++类不是对象,并且在运行时很少或没有类型信息可用。(第121页)

(强调我的)

我一直认为类是对象的同义词,我对这句话的含义感到困惑。 类为什么不是对象,为什么语言是静态的很重要?

C++ 中的类不是对象:类是对如何构建对象的描述,以及对对象类型的引用。

与像Python这样的语言进行比较:在python中,就像在C++中一样,你从类中实例化一个对象。 与C++不同,您使用的类也是一个对象:它通常具有类型 type ,您可以在运行时创建新的对象,像任何其他对象一样操作它们,甚至创建本身具有不同类型的类的对象。

你可能想知道为什么你想要这个,通常你不需要它 - 它就像C++模板元编程,你只需要它,因为你无法以任何其他方式实现你的目标。 在 Python 中解决的问题可能也是这种情况,你在元类中解决的问题C++使用模板元编程来解决。

在C++中,这声明了一个类:

class A {
public:
  int a;
};

而这声明了一个对象:

A a;

不能在运行时询问类,因为可以询问对象。说"对象'a',你的地址是什么?请调用operator+ 。等等。在C++中,由于它的静态类型,说"A类,你的成员列表是什么?请添加一个新成员"b"。

在其他语言中(想到Python),可以通过这种方式操作类,因为每个类也是一个对象。除了用作对象的模板之外,类本身也是一个对象 - 它可以打印,修改等。

例如,一个类可以描述一本书是什么:名称、作者、出版日期、描述。

"书"类的对象将是一本特定的书:C++ Primer Plus,Stephen Prata,2005,一本教C++的书。

因此,类与对象不同。

扩展Andrew Aylett所说的话。

C++中的类不是对象:类是对如何构建对象的描述,以及对对象类型的引用。

此外,在Python或smalltalk等语言中。 一切都是物体。 函数是对象,类是对象。 因此,这些语言是动态类型的,这意味着在运行时检查类型,变量可以采用任何类型。

C++是静态类型的。变量只能采用一种类型,类型检查在编译时执行。

因此,例如在python中,您可以动态修改类。添加函数和字段,因为它是一个对象,可以修改。

这句话指的是这样一个事实,即类不是像C++这样的语言中的一阶实体。在其他语言中,您可以将类作为参数传递给函数,例如,就像您可以将对象或函数作为参数传递一样。

是否是类一阶实体还有更多含义,例如,在运行时修改类的可能性,或检查类的完整内部等。

通常类被发现是动态语言(如 ruby)中的一阶实体,或者在 lisp 的元对象协议中

被发现。

希望这能澄清一点。

类与对象不同。类是(或多或少)类型,对象是实例,类似于以下内容:

int i;
YourClass object;

在这里你不会说iint是一样的——YourClassobject也不是。

该语句想说的是:许多面向对象的语言都是非常面向对象的,因此它们开始使所有内容(或几乎所有内容)成为对象(一个或另一个类)。因此,在许多语言中,class将是某些class class的实例(因此是对象)(这可能会令人困惑)。

这有时具有优势,因为您可以像对待任何其他对象一样对待此类语言中的类(即类型)。你可以用它们做非常动态的事情,比如将它们存储在变量中,甚至在运行时操作类(例如,创建你的程序发现需要的新类)。

看看这个类似 c++ 的伪代码:

YourClass myObject = new YourClass();                // creates an object (an instance)
Class baseClass = myObject.get_class();              // store the class of myObject in baseClass. That's storing a type in a variable (more or less)
Class subClass = myObject.inherit();                 // dynamically create a new class, that only exists in variable subClass (a Class-object), inheriting from baseClass
subClass.add_method(some_function);                  // extend the new class by adding a new method
subClass.get_class() subClass.create_instance();     // declare a new variable (object) of your newly created type 
BaseClass another_onne = subClass.create_instance(); // also valid, since you inherited

这显然不能很好地转换为 c++,因为 c++ 的严格类型。其他语言在打字时更加动态,这种灵活性可以派上用场(并使思维更加复杂;有时两者同时存在)。我仍然认为它解释了原理,如果你了解 c++。

我一直认为类是对象的同义词

OOP文献中的语言有时并不具体。编程语言对对象的概念有些不同,这也无济于事。

是从中创建对象(该类的实例)的模板或定义。也就是说,类提供该类的对象(或类型...稍后会详细介绍。

对象只是该类实例在内存中的一个位置。

维基百科提供了这方面的良好文档。我建议你阅读它:

http://en.wikipedia.org/wiki/Class_(computer_programming)

http://en.wikipedia.org/wiki/Object_(对象oriented_programming)

此外,还有类型的概念。类型(或在某些文献或编程语言中有时称为接口)通常是类型/方法签名(以及可能的行为)的集合。像Java接口和C++纯虚拟类之类的东西倾向于表示类型(但不完全相同)。

然后,符合该类型的类(无论是接口还是纯虚拟类)就是该类型的实现

该类,该类型实现只是如何在内存中构造该类/类型的对象的配方。

当你实例化一个类/类型时,你在内存中具体化、构造该类的实例(对象)。

在C++中,类不是对象,因为类本身没有实例化。C++类不是其他类的实例(请参阅我上面提出的定义)。

OTH,在Java等语言中,类本身由原始类(java.lang.Class)的实例表示。因此,类 X 在内存中有一个与之关联的对象(java.lang.Class 实例)。有了它,有了这个"类"对象,你可以(理论上)实例化或制造类/类型 X 的另一个实例(或对象)。

它可能会令人困惑。我强烈建议您搜索并阅读有关类,类型,原型和对象/实例的文献。

我对这句话的含义感到困惑。类怎么不 对象

如上所述。类不是对象。对象是一个实例,一个由类或类型的"配方"构造和初始化的内存片段。

为什么一种语言是静态的很重要?

本书的这一部分有点误导,因为例如Java是静态类型的,但是类本身可以是对象。也许文本指的是动态类型语言(如JavaScript),其中类也可以是对象或实例。

我的建议是永远不要使用对象这个词,而只是将词汇限制为"类"和"实例"。但这是我个人的偏好。其他人可能不同意,就这样吧。

我可以把它放得越简单,你就能理解它:

对象是类的"物理"实例。它在程序运行时消耗内存。

类描述对象:层次结构、属性、方法。一个类 它就像一个用于创建对象的"模板"。

当一个类被称为一个对象时,这意味着有一个对象在运行时表示该类。在C++中,类在编译时被解散。它们的实例(即对象)只是保存对象字段的字节序列,而不引用类本身。现在,C++确实通过 RTTI 在运行时提供了一些类型信息,但这仅适用于多态类型,不被视为类对象。

运行时缺少表示类的对象是C++中没有反射的原因 - 只是无法获取有关某个类的信息,因为没有表示它的对象。

顺便说一句,C++被认为是一种 2 级语言:对象是类的实例,但类不是任何东西的实例,因为它们只存在于编译类型。在 C# 和 Java 等 3 级语言上,类也是运行时的对象,因此,它们本身是另一个类(Java 中的 Class,C# 中的 Type)的实例。最后一个类是自身的一个实例,因此该语言只有 3 个级别。有些语言的级别更高,但这超出了这个问题的范围......