帮助我理解这一点,如果我考虑所有的C ++标准,包括C ++ 11,那么说我能处理的唯一对象是一个实例是正确的一个班级?
lambda等其他玩家怎么样? POD的实例被视为对象?
我知道这听起来像一个小细节,但大多数时候我发现其他语言的概念难以比较,因为我有这样的问题来定义什么是对象和什么不是,特别是在功能性OOP语言中。 / p>
答案 0 :(得分:8)
如果我考虑所有的C ++标准,包括C ++ 11,那么说我能处理的唯一对象是类的实例是正确的吗?
否,这是不正确的。
在C ++中,术语“对象”指的是存储区域,根据赋予对象的属性(例如其类型)给出特定的解释。
C ++ 11标准的第1.8 / 1段:
C ++程序中的构造创建,销毁,引用,访问和操作对象。 一个对象是一个 存储区域。 [注意:函数不是一个对象,无论它是否占用存储空间 对象的方式。 -end note]一个对象是由一个定义(3.1),一个new-expression(5.3.4)创建的 或者在需要时通过实施(12.2)。对象的属性在对象时确定 被建造。对象可以有一个名称(第3条)。对象具有影响的存储持续时间(3.7) 它的寿命(3.8)。对象具有类型(3.9)。 术语对象类型是指对象所使用的类型 已创建。有些对象是多态的(10.3);该实现生成与之相关的信息 每个这样的对象,可以在程序执行期间确定该对象的类型。对于其他 对象,其中发现的值的解释由表达式的类型决定(第5条) 用来访问它们。
所以基本上int
是一个对象,POD的一个实例是一个对象,当然一个类类型的实例是一个对象。在OOP中,术语“对象”通常意味着仅表示后一个实体 - 但在C ++中,情况并非如此。
如lambdas等其他玩家呢?
Lambdas实际上是用于定义未命名仿函数的语法糖(第5.1.2 / 1段):
Lambda表达式提供了一种创建简单函数对象的简洁方法。 [...]
另外(根据第5.1.2 / 2段):
lambda表达式的评估导致prvalue临时(12.2)。这个临时称为 关闭对象。 [...] [注意:一个闭包 对象的行为类似于函数对象(20.8)。 - 结束记录]
因此,lambdas是一种表达式,其评估结果是创建一个临时对象(所以是的,在某种意义上,人们可以说lambdas也是对象,或者说它们产生一个对象)。 / p>
答案 1 :(得分:2)
在c ++中,对象是具有关联类型
的存储区域 e.g。 int
该地区不一定是连续的
作为一个例子,一个对象的虚拟多重继承部分可以(在某种意义上存在于必须存在的某些情况下)传播
答案 2 :(得分:2)
传统的OOP倾向于将“对象”的概念定义为携带方法和数据的“多态实体”,并且可以从其他对象中引用算法。
对象的C ++定义是-in本质 - “无论什么东西占用空间来保留状态”。 这导致了C ++“对象”具有“值行为”并且“方法”不一定是成员的主要区别,并且对象不一定需要支持运行时多态性。
遵循传统OOP定义的C ++程序最终使用(智能) - (基础) - (指针|引用)引用的类,使用间接机制作为在运行时解析多态的键。
Modern C ++使用对象作为值复制或移动语义,并且在编译时倾向于使用模板和通用算法以及类型特征来解决多态性。
这两件事并不是唯一的,但C ++是故意将两者合并的,因此减少了“对象”的定义,传统的OOP(被引用的类的实例),实际上是 - 削减一半的C ++功能和可能性。
关于lambdas,严格意义上它们是表达式(不是对象本身)返回匿名类型对象。
所以说它们是对象是不合适的:a+b
它本身不是一个对象:它生成一个对象(表达式的结果)。同样适用于[](){}
:它本身不是一个对象:它产生一个对象,你甚至可以存储,如
auto fn = [](){}; //create a lambda and assign to fn.
fn(); //just calls it
fn类型类似于
class lambda_uniquename
{
public:
void operator()()
{}
};
此处的对象不是lambda
类,而是fn
变量。