5

帮助我理解这一点,如果我考虑所有 C++ 标准,包括 C++11,那么说我可以处理的唯一对象是类的实例是正确的吗?

其他玩家,例如 lambdas 呢?POD 的一个实例被认为是一个对象?

我知道这听起来像是一个小细节,但大多数时候,当我在定义什么是对象和什么不是对象时遇到此类问题时,我发现其他语言的概念很难比较,尤其是在函数式 OOP 语言中。

4

3 回答 3

8

如果我考虑所有 C++ 标准,包括 C++11,那么说我可以处理的唯一对象是类的实例是正确的吗?

,这是不正确的。

在 C++ 中,术语“对象”是指根据赋予对象的属性(例如其类型)给出特定解释的存储区域。

根据 C++11 标准的第 1.8/1 段:

C++ 程序中的构造创建、销毁、引用、访问和操作对象。一个对象是一个存储区域。[注意:函数不是对象,无论它是否像对象那样占用存储空间。—尾注]对象由定义(3.1)、新表达式(5.3.4)或实现(12.2)在需要时创建。对象的属性是在创建对象时确定的。一个对象可以有一个名称(第 3 条)。对象具有影响其生命周期 (3.8) 的存储持续时间 (3.7)。一个对象有一个类型(3.9)。术语对象类型是指创建对象的类型. 一些对象是多态的(10.3);该实现生成与每个此类对象相关联的信息,从而可以在程序执行期间确定该对象的类型。对于其他对象,其中找到的值的解释取决于用于访问它们的表达式的类型(第 5 条)。

所以基本上anint是一个对象,一个POD的实例是一个对象,当然一个类类型的实例也是一个对象。在 OOP 中,术语“对象”通常仅表示后一个实体——但在 C++ 中并非如此。

其他玩家,例如 lambdas 呢?

Lambda 实际上是定义未命名函子的语法糖(第 5.1.2/1 段):

Lambda 表达式提供了一种简洁的方式来创建简单的函数对象。[...]

另外(根据第 5.1.2/2 段):

对 lambda 表达式的求值会产生一个临时纯右值 (12.2)。这个临时的称为闭包对象。[...] [注意:闭包对象的行为类似于函数对象(20.8)。——<em>尾注]

因此,lambda 是表达式,其求值会导致创建一个临时对象(所以是的,在某种意义上可以说 lambda 也是对象,或者更确切地说,它们产生一个对象)。

于 2013-04-11T09:38:12.977 回答
2

传统的OOP倾向于将“对象”的概念定义为携带方法和数据的“多态实体”,并且可以从其他对象和算法中引用。

对象的 C++ 定义本质上是“任何事物都需要空间来保持状态”。这导致 C++“对象”具有“值行为”和“方法”不一定是成员的主要区别,并且对象不一定需要支持运行时多态性。

遵循传统 OOP 定义的 C++ 程序,以 (smart)-(base)-(pointers|reference) 引用的类结束,使用间接机制作为在运行时解决多态性的关键。

现代 C++ 使用对象作为具有值复制或移动语义,并倾向于在编译时使用模板和通用算法和类型特征来解决多态性。

这两件事不是相互对立的,但 C++ 有意将两者合并,因此减少了传统 OOP 的“对象”定义(要引用的类的实例),实际上是削减了一半的 C++ 特性和可能性。

关于 lambda,严格意义上来说,它们是返回匿名类型对象的表达式(不是对象本身)。

所以说它们是对象是不恰当的:a+b它本身不是一个对象:它产生一个对象(表达式的结果)。同样适用于[](){}:它本身不是一个对象:它产生一个对象,你甚至可以存储,比如

auto fn = [](){}; //create a lambda and assign to fn.
fn();             //just calls it

fn 类型类似于

class lambda_uniquename
{
public:
   void operator()()
   {}
};

这里的对象不是lambda类,而是fn变量。

于 2013-04-11T12:23:50.293 回答
2

在 C++ 中,对象是具有关联类型的存储区域

例如一个int

该区域不一定是连续的

举个例子,一个对象的虚拟多重继承部分可以(在某种意义上,在某些情况下存在它必须存在的地方)分布在

于 2013-04-11T09:39:02.060 回答