原始C ++指针是第一类对象吗?

时间:2010-04-22 23:14:05

标签: c++ programming-languages

根据Wikipedia

对象是第一类的:

  • 可以存储在变量和数据结构中
  • 可以作为参数传递给子程序
  • 可以作为子程序的结果返回
  • 可以在运行时构建
  • 具有内在身份(独立于任何给定名称)

有人曾告诉我原始指针不是第一类对象,而像std :: auto_ptr这样的智能指针是。但对我来说,C ++中的原始指针(对象或函数)在我看来确实满足上述条件才有资格作为第一类对象。我错过了什么吗?

5 个答案:

答案 0 :(得分:3)

维基百科中“一流”的定义不正确。在编程语言中,如果实体不需要编译器的任何特殊处理并且可以像语言中的任何其他对象那样被解释,理解,使用等,则该实体被认为是“第一类”。 C ++中的指针不是第一类对象的原因是指针*p的{​​{1}}不会被解释为简单地调用重载的运算符*就像它对任何其他对象一样;相反,编译器必须特别根据它是指针类型的事实来对待p。传递指针或引用时,你不能简单地传递任何值对象(其中一些值对象碰巧是指针),但实际上你说它是一个不同的类型(指针类型或引用类型,代替值类型),其解释/用法取决于其类型。

所有对象都是一流的语言的一个很好的例子是Python。在Python中,一切都有某种与之相关的类型,它可以被视为一个对象,它可以有成员,函数等。作为一个极端的例子,即使是Python中的函数也只是包含代码并且碰巧可以调用的对象;实际上,如果你试图使用__call__成员函数调用函数(类似于在C ++中重载operator(),以及其他非函数对象可以提供),普通函数将返回一个函数包装器作为结果(这样您就不必将功能视为一种特殊情况)。您甚至可以像添加其他对象一样向函数添加成员。这是一个这样的例子:

>>> def f(x):
...     return x;
... 
>>> func = f;
>>> print f.__class__

>>> print f(5)
5
>>> print f.__call__(5)
5
>>> f.myOwnMember = "Hello world!"
>>> print f.myOwnMember
Hello world!

我为C ++文章中的Python道歉,但如果没有对比,很难解释这个概念。

答案 1 :(得分:2)

维基百科的文章很糟糕(因为我同意“引用需要”),但你没有遗漏任何东西:根据维基百科的定义,并且根据任何理智的定义,原始C ++指针是第一个 - 类对象

如果有人愿意通过Google学术搜索帮助我进行一些搜索,我真的希望看到维基百科的文章已修复。我是一名主题专家,但我也非常忙碌 - 我很想有一个合作伙伴来处理这个问题。

答案 2 :(得分:1)

来自wiki

  

在计算中,是一流的对象   (也是价值,实体和公民),在   特定的背景   编程语言,是一个实体   可以作为参数传递,   从子程序返回,或   分配到变量。1 In   计算机科学术语的具体化   在引用该过程时使用   (技术,机制)制作   一流的东西   对象。[引证需要]

我在wiki-pedia中包含了整个条目以供上下文使用。根据这个定义 - 一个可以作为参数传递的实体 - C ++指针将是一个第一类对象。

支持该论点的其他链接: catalysoft wapedia

具体化:指的是使某事成为第一类对象的过程(技术,机制)

答案 3 :(得分:1)

正如迈克评论的那样,对象这里似乎有点混淆。您的朋友似乎在“第一类对象”和对象之间混淆了“C ++类的实例”,两个非常不同的东西,其中单词对象用于完全不同的两件事。

在面向对象的编程中,单词Object用于说明收集数据字段的一些数据结构和操作它们的方法。使用C ++,您可以在类中定义它们,获得继承等等。

另一方面,在表达“第一类对象”中,单词对象具有更广泛的含义,不限于面向对象语言的对象。整数有资格作为第一类对象,指针也可以。我认为具有其他含义的“对象”并不真正有资格作为C ++中的第一类对象(它们在其他OO编程语言中有用),因为它们对参数传递有限制(但你可以传递指针或对它们的引用,区别不是那么大。)

然后事情与你朋友说的完全相反:指针是第一类对象,但不是C ++类的实例,智能指针是C ++类的实例,但不是第一类对象。

答案 4 :(得分:1)

实际上两者 - “指针是FCO”和“指针不是FCO” - 都是正确的。我们需要在各自的背景下进行陈述。 (FCO - 头等对象)

当我们在C ++中讨论'指针'时,我们谈论的是一种存储其他数据地址的数据类型。现在这是否是FCO,实际上取决于我们如何设想使用它。不幸的是,这种使用语义不是内置于C ++中的指针。

如果我们仅使用指针“指向”数据,它将满足作为FCO的要求。但是,如果我们使用指针“保持”数据,则它不再被视为FCO,因为它的副本和赋值语义不起作用。这种“资源处理”指针(或更直接称为“原始指针”)是我们对智能指针研究背景的兴趣。这些不是FCO,而相应的智能指针是。相比之下,仅仅跟踪指针将继续满足FCO的要求。

“现代C ++设计”一书中的以下段落很好地阐明了这一点。

我引用智能指针章节:

  

具有值语义的对象是   您可以复制和分配的对象   至。类型int是完美的例子   一流的对象。你可以创建,   复制,并更改整数值   自如。你用的指针   在缓冲区中迭代也有价值   语义 - 你初始化它指向   到缓冲区的开头,和   你碰到它直到你到达终点。   在此过程中,您可以复制其值   其他变量保持临时性   结果

     

使用包含值的指针   然而,分配了新的故事   是非常不同的。一旦你有了   写入

     

Widget * p = new Widget;        变量p不仅指向,而且还拥有内存   为Widget对象分配。这个   是因为以后你必须发出删除   p确保Widget对象是   被摧毁,其记忆被释放。   如果在行之后就行了   显示你写了

     

p = 0; //为p分配其他东西        你失去了p先前指向的对象的所有权   根本没有机会抓住   它再次。你有资源泄漏,   和资源泄漏从来没有帮助。

我希望这可以澄清。