类怎么不是C++中的对象
How are classes not objects in C++?
我正在阅读"设计模式:可重用面向对象软件的元素"(特别是关于原型设计模式的章节),它指出......
"原型对于静态语言特别有用,例如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;
在这里你不会说i
和int
是一样的——YourClass
和object
也不是。
该语句想说的是:许多面向对象的语言都是非常面向对象的,因此它们开始使所有内容(或几乎所有内容)成为对象(一个或另一个类)。因此,在许多语言中,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 个级别。有些语言的级别更高,但这超出了这个问题的范围......
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- CMake-按正确顺序将项目与C运行时对象文件链接
- 空基优化子对象的地址
- 将对象数组的引用传递给函数
- 你能重载对象变量名本身返回的内容吗
- C++使用整数的压缩数组初始化对象
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 将对象移动到std::shared_ptr
- 代理对象的常量正确性
- 提升 ASIO 无法识别计时器对象
- 将Ref对象作为类成员
- 将包含C样式数组的对象初始化为成员变量(C++)
- 如何返回一个类的两个对象相加的结果
- 使用std::函数映射对象方法
- 是否需要删除包含对象的"pair"?
- 如何在自删除后将对象设置为nullptr
- 迭代时从向量和内存中删除对象
- 构造对象的歧义
- 使用"std::unordereded_map"映射到"std::list"对象