代码之家  ›  专栏  ›  技术社区  ›  QBziZ

创建对象:新建还是新建?

  •  6
  • QBziZ  · 技术社区  · 5 年前

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

    8 回复  |  直到 15 年前
        1
  •  12
  •   jalf    15 年前

    只是出于好奇:为什么C++选择A=新A而不是A==AN新作为实例对象的方式?后者看起来更像是面向对象的吗?

    是吗? 这取决于你如何定义“面向对象”。

    如果你定义它,Java的方式就是“一切都必须有形式的语法”。 X.Y “哪里 X 是一个对象,并且 Y 不管你想对那个物体做什么,是的,你是对的。这不是面向对象的,Java是面向对象编程的顶峰。

    但幸运的是,也有一些人认为“面向对象”应该与 行为 而不是在对象上使用的语法。从本质上讲,它应该归结为 Wikipedia 佩奇说:

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

    注意,它对语法没有任何影响。它没有说“并且必须通过指定一个对象名,后跟一个点,后跟函数名来调用每个函数”。

    考虑到这个定义, foo(x) 与面向对象 x.foo() . 重要的是 x 是一个对象,也就是说,它由数据字段和一组方法组成,通过这些方法可以对它进行操作。在这种情况下, foo 显然是这些方法中的一个,不管它是在哪里定义的,也不管调用它时使用哪种语法。

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

    所以,为什么会 A.new 更面向对象?这个表单如何为您提供“更好”的对象?

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

    如果 new 曾经是每一个类的成员,这意味着每一个类都必须定义 它自己 新的 操作。而当它是非成员时,每个类都可以重用同一个类。既然功能是相同的(分配内存、调用构造函数),为什么不把它放在所有类都可以重用的开放位置呢?(先发制人:当然,也一样 新的 在这种情况下,也可以通过从某个公共基类继承来重用实现,或者只是通过一点编译器的魔力。但归根结底,当我们可以首先将机制置于课堂之外时,何必费心呢)

        2
  •  11
  •   CB Bailey    15 年前

    这个 . 在C++中只用于成员访问,所以点的右边总是一个 对象 而不是 类型 . 如果有什么事的话,做起来更合乎逻辑 A::new() A.new() .

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

        3
  •  3
  •   UncleBens    15 年前

    我觉得最大的困惑是 新的 有两种含义:一种是内置的新表达式(它结合了内存分配和对象创建),另一种是重载运算符new(它只处理内存分配)。第一,据我所见,是一些你不能改变其行为的东西,因此把它伪装成一个成员函数是没有意义的。(或者它必须是——或者看起来像——一个没有类可以实现/重写的成员函数!!)

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

     int* p = int.new;
    

    C++不是纯OOP语言,不是所有的事物都是对象。

    C++还允许使用自由函数(这是一些作者和SC+L设计中的示例集所鼓励的),C++程序员应该对此感到满意。当然,新的表达式不是一个函数,但是我看不出含糊地提示自由函数调用的语法如何能在自由函数调用非常常见的语言中让任何人望而却步。

        4
  •  2
  •   Test    15 年前

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

    CObject *p = (CObject*)malloc(sizeof *p);
    ...
    p = new(p) CObject;
    p->DoSomthing();
    ...
    
        5
  •  1
  •   Etan    15 年前

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

        6
  •  1
  •   Pavel Shved    15 年前

    实际上,可以用类似 A.new ,如果添加正确的方法:

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

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

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

    除非已经超载,否则使用 新的 算子优先 分配原始内存 ,然后调用在分配的内存中构建它的对象构造函数。因为这里涉及到“原始”的低级操作,所以它应该是一个单独的语言操作符,而不仅仅是类方法之一。

        7
  •  0
  •   Andrew Keith    15 年前

    我想没有理由。它是A=新的A,因为它是第一个这样起草的。事后看来,它应该是a=a.new();

        8
  •  0
  •   Ashish    15 年前

    为什么每个班级都应该有新的学生?

    我认为根本不需要,因为新的目标是 分配适当的内存并通过调用构造函数构造对象。 因此,新的行为是独特的,独立的,不分阶级。那么为什么不使是可恢复的呢?

    当您想自己进行内存管理时,您可以覆盖new(即只分配一次内存池,并根据需要返回内存)。

    推荐文章