0

在大多数 OOP 书籍和文章中,我们读到了类似这样的关于构造函数的内容:

构造函数是类中的一种特殊方法,它的名称与类名相同,并且没有返回类型。

所以我们的构造函数是这样的形式:

class MyClass {
    public: /* no return type */ MyClass();
}

好吧,这个定义与 OOP 原则有些冲突:方法必须有一个返回类型(即使void),并且在一个对象中,我们不能有 2 个同名的成员,所以一个方法不能与类的名称同名。

我认为我们可以将定义更改为这样的:

构造函数是类中的一种特殊方法,它没有名称——匿名或无名方法——它的返回类型是类(的类型)。

所以我们会有:

class MyClass {
    public: MyClass /* no method name */ ();
}

在第二个定义中:我们被允许在大多数 OOP 语言中使用匿名方法,并且我们的方法具有真正的返回类型。

var obj = new MyClass(); 

构造函数被调用,并且obj是 的一个实例MyClass,所以构造函数有一个返回值。另一方面,new MyClass()是在名为 的对象的蓝图上调用可访问匿名方法的协定MyClass

你怎么看?我错了还是我们可以使用这个定义或从这个角度来看待构造函数?

更新: 为什么我会下台并关闭选票?请解释。

4

2 回答 2

4

Operatornew做了两件事:

  1. 为新对象分配内存(在您的示例中,指向该内存的指针分配给 obj )。
  2. 调用使用默认值初始化对象的构造函数。

所以,从这个意义上说,构造函数不返回任何东西。它new是返回对象的运算符。构造函数作为装饰器工作:它接收一块内存并使用默认值初始化该内存中的各种字节。

它还回答了您的第一点,即构造函数必须具有返回类型。由于构造函数只初始化new操作符分配的一些数据,它不能返回任何东西,因为如果它确实想返回一些东西,那么表达式new MyClass()实际上必须同时返回两种类型!一种类型是运算符分配的对象new,第二种类型是构造函数修饰的同一对象。

如果您想对定义如此挑剔,我宁愿建议将method描述中的名称更改为其他名称(也许是装饰器,例如设计模式中的名称?)。

谁说方法必须返回类型?抽象方法呢,它们返回任何东西吗?

编辑回答一些问题:

是的,抽象方法有一个返回类型,但它们实际上并不返回任何东西,只有实现它们定义的接口的方法。我的意思是表明,并非所有定义为方法的东西都必须返回一个类型。某些方法(或某些语言结构)确实会返回某些内容,而有些则不会,无论您如何称呼它们。

我猜在构造函数的情况下,用不返回任何东西的方法来定义它们会更容易,因为它们与任何其他常规方法非常相似,除了它们实际上不返回任何东西,而不是试图为不返回任何内容的类似方法的构造构建另一个定义。

运算符new没有说创建对象。它只是一个运算符,一种语言结构。当编译的代码new实际上不再存在时,它会被一些汇编代码替换,以分配和初始化一块代表对象的内存。

new MyClass()我们来一一拆解执行时所采取的步骤:

  1. 运算符new分配一块内存,其大小需要存储类MyClass及其所有父类和子类的所有变量和元数据。
  2. 运算符现在执行类的所有父类MyClass(如果有)的构造函数。
  3. 运算符执行类的所有子类的构造函数MyClass(存储在其中的成员变量MyClass不是内置类本身)。
  4. 运算符最终执行类的构造函数MyClass
  5. 运算符new返回创建的对象(或指向已分配内存的指针)。

很少只有一个构造函数可以执行。如果该类具有父类并在其中包含任何自定义类,则new操作员必须执行一些(如果不是几十个)构造函数才能返回对象。如果每个构造函数都必须返回一些东西,那么所有的返回类型会去哪里,如果我们不能对构造函数返回的任何东西做任何事情,那么这样做的意义何在?

运算符是什么动物?

我认为这里令人困惑的是运算符的定义。运算符不是调用的方法。认为new说创建一个对象与+说添加两个对象或=说比较对象一样错误。运算符可以重载,但原则是运算符是定义语言(编译后的汇编代码)执行的操作的语言结构,例如将两个对象的总和分配给一个变量,创建一个对象等。请参阅wikipedia 上的运算符

于 2013-05-14T22:32:07.667 回答
0

谁在乎书中对构造函数的描述?为什么要打扰语义?

构造函数的唯一目的是构造和实例化一个对象,没有对象就没有 OOP。构造函数做一些事情并且不返回值,所以这就是为什么它们被许多书籍标记为“专门的方法”并且使用专门的词正是因为它们不需要在其签名中使用 void 关键字。

很清楚构造函数做什么以及它们是如何做的,所以你的问题归结为文学中是否正确描述了构造函数,虽然我碰巧认为它们是,正是因为使用了“专业”这个词,所以重点是什么在那种程度的解剖上浪费时间?

如果您直接访问源代码 (MSDN),您会在 C# Programming Guide 的构造函数中找到它:

每当创建类或结构时,都会调用其构造函数。一个类或结构可能有多个接受不同参数的构造函数。构造函数使程序员能够设置默认值、限制实例化并编写灵活且易于阅读的代码。

正如您所看到的,MSDN 并未将构造函数标记为“专用方法”(或其他任何东西),它只是清楚而简洁地描述了构造函数是什么以及它的目的是什么。这只是他们设计框架的一部分,所以一些作者使用什么隐喻来描述构​​造函数是完全无关的......

最后,引用《框架设计指南》:

没有完美的设计。设计就是权衡取舍,为了做出正确的决定,您需要了解选项、它们的优点和缺点。如果您发现自己认为自己的设计没有权衡取舍,那么您可能错过了一些重要的东西,而不是找到灵丹妙药。

使构造函数按照它们的方式很容易被视为该引用中描述的这种权衡。

于 2013-05-14T23:11:42.803 回答