请告诉我为什么构造函数不返回任何值。我想要一个完美的技术理由向我的学生解释为什么构造函数没有任何返回类型。
答案 0 :(得分:102)
构造函数实际发生的是运行时使用编译器生成的类型数据来确定在内存中存储对象实例需要多少空间,无论是在堆栈上还是在堆上。
此空间包括所有成员变量和vtbl。分配此空间后,构造函数将作为实例化和初始化过程的内部部分进行调用,以初始化字段的内容。
然后,当构造函数退出时,运行时返回新创建的实例。因此构造函数不返回值的原因是因为它不是由代码直接调用,而是由运行时中的内存分配和对象初始化代码调用。
它的返回值(如果在编译为机器代码时实际上有一个)对用户来说是不透明的 - 因此,你不能指定它。
答案 1 :(得分:12)
好吧,在某种程度上它返回刚刚构建的实例。
你甚至可以这样称呼它,例如Java
Object o = new Something();
看起来就像调用带有返回值的“常规”方法
Object o = someMethod();
答案 2 :(得分:4)
(我偏向于C ++,所以关于其他语言,请加上一点点。)
简短回答:您不希望必须明确检查代码中每个对象构造是否成功。
更长的答案:在C ++中,动态调用构造函数以及全局和自动分配的对象。在此代码中
void f()
{
std::string s;
}
s
(std::string::string()
)的构造函数无法返回任何值。要么成功 - 然后我们可以使用该对象,或者它抛出异常 - 我们永远不会有机会尝试使用它。
IMO,这就是应该的样子。
答案 3 :(得分:3)
构造函数应该如何返回返回值? new
运算符返回新创建的实例。你不打电话给ctor,new
做到了。
MyClass instance = new MyClass();
如果ctor会返回一个值,如下所示:
public int MyClass()
{
return 42;
}
你会在哪里收到整数?
答案 4 :(得分:2)
当您调用构造函数时,返回值是新对象:
Point pt = new Point(1,2);
但是在构造函数本身中,你实际上并没有创建和返回对象;它是在您的代码开始之前创建的,您只需设置初始值。
Point::Point(int x, int y) {
this->x = x;
this->y = y;
}
缺少返回类型反映了构造函数的使用方式与其他函数不同。返回类型null
虽然在技术上是准确的,但并不能很好地反映代码使用的事实,就好像它返回一个对象一样。但是,任何其他返回类型都表明您的代码最后应该return
,这也是错误的。
答案 5 :(得分:1)
构造函数是初始化对象的新实例时自动调用的一些方法。
如果您需要将对象初始化为给定状态并运行少量默认方法,则此方法就存在。
实际上你可以想象构造函数总是返回创建的对象的实例,这将是一个好的图像。
答案 6 :(得分:1)
所有答案都偏向于C ++ / Java。构造函数没有理由不返回语言设计以外的值。
从更广泛的意义上看一个构造函数:它是一个构造一个新对象的函数。你可以用C:
编写完全有效的构造函数typedef struct object object;
int object_create( object **this );
这是C中的完美OOP,构造函数返回值(这也可以称为工厂,但名称取决于意图)。
但是,为了自动创建对象(例如,为了满足某些类型转换或转换),必须定义一些规则。在C ++中,有一个无参数构造函数,如果未定义,则由编译器推断。
讨论比我们想象的更广泛。面向对象编程是一个描述关于编程的思维方式的名称。你几乎可以用任何语言编写OO:你需要的只是结构和功能。像C ++和Java这样的主流语言非常普遍,我们认为它们定义了“方式”。现在看看Ada中的OO模型:它远不是C ++的模型,但仍然是OO。我确信像Lisp这样的语言还有其他一些做OO的方法。
答案 7 :(得分:1)
尚未讨论过的一点是,类“foo”的构造函数不仅在创建foo实例时,而且在创建从foo派生的类的实例时也必须可用。如果缺少泛型(在设计Java,C ++或.net时不可用),foo的构造函数将无法返回任何派生类的对象。因此,需要发生的是派生类对象通过其他方式创建,然后可用于foo的构造函数(然后它可以在执行初始化时将该对象用作foo)。
答案 8 :(得分:1)
构造函数不是由用户代码直接调用的。它在运行时由内存分配和对象初始化代码调用。其值对用户不可见。
答案 9 :(得分:1)
即使构造函数的VM实现不返回任何值,实际上也是如此 - 新对象的引用。然后,在一个语句中能够存储新对象的引用和附加返回值中的一个或两个,这在语法上会很奇怪和/或令人困惑。
答案 10 :(得分:0)
方法在显式调用时将值返回到其调用方方法。由于构造函数没有显式调用,它将返回值的对象。构造函数的唯一目的是初始化类的成员变量。
答案 11 :(得分:0)
构造函数不返回任何内容,甚至不返回Void。尽管一些答案提到了Constructor确实返回了对新创建的对象的引用,但这是不正确的。这是返回对象的新运算符。
那为什么构造函数不返回任何值
因为它不应该返回任何东西。构造函数的全部目的是通过设置初始值来初始化对象的当前状态。
那为什么它甚至不返回Void
这实际上是一个设计约束,用于将其与方法区分开。 public void className()在Java中是完全合法的,但它表示方法而不是构造函数。为了使编译器了解它是构造函数,需要一种区分它的方法。
答案 12 :(得分:0)
因此构造函数不返回值的原因是因为它不是由代码直接调用,而是由运行时中的内存分配和对象初始化代码调用。它的返回值(如果它在编译成机器代码时实际上有一个)对用户来说是不透明的 - 因此,你不能指定它。
答案 13 :(得分:0)
我会在答案中使用Java作为我的语言。
class SayHelloOnCreation {
public SayHelloOnCreation() {
System.out.println("Hello, Thanks For Creating me!");
}
}
class Test {
public static void main(String[]args) {
SayHelloOnCreation thing = new SayHelloOnCreation(); //This line here, produces an output - Hello, Thanks For Creating me!
}
}
现在让我们看看这里发生了什么。在java中,我们使用 new 关键字来创建类的实例。正如您在代码中看到的那样, SayHelloOnCreation thing = new SayHelloOnCreation(); ,赋值运算符之后的表达式在赋值完成之前运行。因此,使用关键字 new ,我们调用该类的构造函数( SayHelloOnCreation()),此构造函数在Java堆上创建对象。创建对象后,对该对象的引用将分配给 SayHelloOnCreation 类型的 thing 引用。
我想保留的重点是,如果允许构造函数具有返回类型,首先语言的强类型性质会受到影响(请记住我在这里谈论Java。)
其次,这里创建了类 SayHelloOnCreation 的对象,所以默认情况下我猜构造函数返回相同类型的引用,以避免 ClassCastException 强>
答案 14 :(得分:0)
答案 15 :(得分:0)
当你意识到创建对象时,将自动调用构造函数所以现在假设构造函数返回一个int值。所以代码应该是这样的......
Class ABC
{
int i;
public:
int ABC()
{
i=0;
return i;
}
.......
};
int main()
{
int k= ABC abc; //constructor is called so we have to store the value return by it
....
}
但是你知道任何编程语言都不可能像int k= ABC abc;
这样的陈述。希望你能理解。
答案 16 :(得分:0)
根据我对OO设计方法的了解,我会说以下内容:
1)通过允许构造函数返回值,框架开发人员将允许程序在未处理返回值的瞬间崩溃。为了保持程序工作流程的完整性,不允许从对象初始化返回值是一个有效的决定。相反,语言设计者会建议/强制编码人员使用getter / setter - 访问方法。
2)允许对象在初始化时返回值也会打开可能的信息泄漏。特别是当对变量/方法应用多个层或访问修改时。
答案 17 :(得分:0)
我们不能独立调用构造函数。相反,只要创建对象,它们就会自动调用。 例如:
MyDate md = new Mydate(22,12,2012);
在上面的例子中,new
将返回一个由md保存的内存位置,并且以编程方式我们不能在单个语句中返回多个值。
所以构造函数不能返回任何东西。
答案 18 :(得分:0)
对于C#,声明对象的语法是:
classname objectname= new constructor();
根据这一行,如果我们使用赋值运算符(=)那么它应该返回一些值。但是构造函数的主要目标是为变量赋值,所以当我们使用new关键字时,它创建该类的实例,构造函数为该特定对象实例的变量赋值,因此构造函数返回该对象的赋值。实例