6

只是出于好奇:为什么 C++ 选择a = new A而不是a = A.new作为实例化对象的方式?后者不是更像是面向对象的吗?

4

8 回答 8

12

只是出于好奇:为什么 C++ 选择 a = new A 而不是 a = A.new 作为实例化对象的方式?后者不是更像是面向对象的吗?

可以?这取决于您如何定义“面向对象”。

如果您按照 Java 的方式定义它,“一切都必须具有“ X.Y”形式的语法,其中X是一个对象,并且Y是您想对该对象执行的任何操作,那么是的,您是对的。这不是面向对象,而Java是OOP编程的巅峰之作。

但幸运的是,也有少数人认为“面向对象”应该与对象的行为有关,而不是与对象使用的语法有关。基本上它应该归结为维基百科页面所说的:

面向对象编程是一种编程范式,它使用“对象”——由数据字段和方法及其交互组成的数据结构——来设计应用程序和计算机程序。编程技术可能包括信息隐藏、数据抽象、封装、模块化、多态性和继承等特性

请注意,它没有说明语法。它没有说“你必须通过指定一个对象名称后跟一个点,然后是函数名称来调用每个函数”。

给定这个定义,foo(x)它与x.foo(). 重要的是它x是一个对象,也就是说,它由数据字段和一组可以用来操作它的方法组成。在这种情况下,foo显然是这些方法之一,无论它是在哪里定义的,也无论在调用它时使用哪种语法。

C++ 大师们很久以前就意识到了这一点,并撰写了诸如此类的文章。对象的接口不仅仅是一组成员方法(可以用点语法调用)。它是可以操纵对象的一组函数。他们是会员还是朋友并不重要。只要对象能够保持一致,它就是面向对象的,也就是说,它能够防止任意函数干扰它。

那么,为什么会A.new更加面向对象呢?这种形式如何为您提供“更好”的对象?

OOP 背后的关键目标之一是允许更多可重用的代码。

如果new是每个类的成员,那就意味着每个类都必须定义自己的 new操作。而当它是非成员时,每个类都可以重用同一个。既然功能是一样的(分配内存,调用构造函数),为什么不把它放在所有类都可以重用的地方呢?(先发制人的挑剔:当然,new在这种情况下,同样的实现也可以被重用,通过从一些公共基类继承,或者只是通过一点编译器魔法。但最终,为什么要麻烦,当我们可以把机制放在首先在课堂之外)

于 2009-10-17T10:43:48.530 回答
11

C++ 中的.仅用于成员访问,因此点的右侧始终是object而不是type。如果有的话,这样做会A::new()A.new().

在任何情况下,动态对象分配都是特殊的,因为编译器分两步分配内存和构造对象,并在任一步骤中添加代码来处理异常,以确保内存永远不会泄漏。让它看起来像一个成员函数调用而不是一个特殊的操作可以被认为是模糊了操作的特殊性质。

于 2009-10-17T09:34:04.660 回答
3

我认为这里最大的困惑是new有两个含义:有内置的 new 表达式(它结合了内存分配和对象创建),然后是可重载的运算符 new(它只处理内存分配)。据我所知,第一个是你无法改变其行为的东西,因此将它伪装成成员函数是没有意义的。(或者它必须是 - 或看起来像 - 一个没有类可以实现/覆盖的成员函数!!)

这也会导致另一个不一致:

 int* p = int.new;

C++ 不是纯粹的 OOP 语言,因为并非一切都是对象。

C++ 还允许使用自由函数(一些作者和 SC++L 设计中的示例都鼓励使用),C++ 程序员应该对此感到满意。当然,new-expression 不是函数,但我不明白在自由函数调用非常普遍的语言中,模糊地提醒自由函数调用的语法如何让任何人望而却步。

于 2009-10-17T10:16:23.740 回答
2

请阅读代码(它有效),然后你会有不同的想法:

CObject *p = (CObject*)malloc(sizeof *p);
...
p = new(p) CObject;
p->DoSomthing();
...
于 2009-10-17T10:58:44.753 回答
1

A.newAwhilea = new A分配内存然后调用对象的构造函数的静态函数

于 2009-10-17T09:33:39.570 回答
1

A.new实际上,如果您添加正确的方法,您可以使用类似的东西来实例化对象:

class A{
  public: static A* instance()
  {  return new A(); }
};

A *a = A::instance();

但事实并非如此。语法也不是这样:您可以通过检查它的右侧来区分::和“操作”。.

我认为原因是内存管理。在 C++ 中,与许多其他面向对象的语言不同,内存管理由用户完成。没有默认的垃圾收集器,尽管标准和非标准库包含它,以及管理内存的各种技术。因此程序员必须看到操作符new才能理解这里涉及到内存分配

除非已经重载,否则new运算符的使用首先分配原始内存,然后调用在分配的内存中构建它的对象构造函数。由于此处涉及“原始”低级操作,因此它应该是单独的语言运算符,而不仅仅是类方法之一。

于 2009-10-17T09:37:18.857 回答
0

我认为没有理由。它的 a = new a 只是因为它最初是这样起草的。事后看来,它可能应该是 a = a.new();

于 2009-10-17T09:33:07.867 回答
0

为什么每个班级都应该有单独的新人?

I dont think its needed at all because the objective of new is to allocate appropriate memory and construct the object by calling constructor. Thus behaviour of new is unique and independent irrespective of any class. So why dont make is resuable ?

You can override new when you want to do memory management by yourself ( i.e. by allocating memory pool once and returning memory on demand).

于 2009-10-27T09:13:12.907 回答