C++ C++;构造函数没有返回类型。到底为什么?
我在谷歌上搜索过这篇文章,读过很多帖子,但是有太多不同的答案,所有这些答案都是合乎逻辑的,我想知道这方面的专家是否可以解开这个问题的谜团 有人说没有返回是因为没有返回的方法-语法禁止它-是的,这是有道理的,但我相信所有函数都必须返回一些东西,不是吗? 另一些人说构造函数会返回新创建的对象本身,这似乎是有意义的,因为构造函数上使用了赋值运算符。C++ C++;构造函数没有返回类型。到底为什么?,c++,compiler-construction,constructor,return,C++,Compiler Construction,Constructor,Return,我在谷歌上搜索过这篇文章,读过很多帖子,但是有太多不同的答案,所有这些答案都是合乎逻辑的,我想知道这方面的专家是否可以解开这个问题的谜团 有人说没有返回是因为没有返回的方法-语法禁止它-是的,这是有道理的,但我相信所有函数都必须返回一些东西,不是吗? 另一些人说构造函数会返回新创建的对象本身,这似乎是有意义的,因为构造函数上使用了赋值运算符。 还有一些人有其他有趣的解释。构造函数构造到位,不需要返回任何东西 我相信所有函数都必须返回一些东西 空格? < P>构造函数缺少返回类型——甚至不包括代码
还有一些人有其他有趣的解释。构造函数构造到位,不需要返回任何东西 我相信所有函数都必须返回一些东西 <代码>空格? < P>构造函数缺少返回类型——甚至不包括代码> Value——这意味着不能从C++代码调用构造函数。这就是重点。调用构造函数没有意义。将调用构造函数设为非法可以消除这种类型的用户错误的可能性 编辑 barnes是对的,你不能调用构造函数的最终原因是它们没有名字。(即使这样也忽略了您可以通过placement new间接调用构造函数。) 重试:
您不能调用C++代码中的构造函数,因为构造函数没有名称。使构造函数不具有返回类型向程序员强调,构造函数是一种与其他函数截然不同的函数。如果构造函数返回任何内容,那么它实际返回的内容取决于供应商。构造函数没有指定返回类型,因为它是冗余的:除了正在构造的类型之外,没有任何类型是构造函数可能“返回”的。我将“return”放在引号中,因为从技术上讲,构造函数不会返回任何东西:当在静态上下文中调用它们时,它们会就地初始化实例;在动态上下文中调用构造函数时,返回内容的是操作符
new
,而不是构造函数。构造函数不像其他函数那样被调用,因此它们不像其他函数那样返回。它们作为某些构造的副作用执行(cast、new
、变量定义、ctor初始值设定项列表、按值传递、按值返回)
但我相信所有函数都必须返回一些东西,不是吗
否。从函数返回值意味着什么?好的,实现的ABI将指定对于某些返回类型,函数将某些寄存器或堆栈指针某个偏移处的某些内存设置为函数“返回”的值
显然,在调用构造函数或void函数后,寄存器和内存存在并包含数据,但该语言表示这些函数不返回任何内容,因此ABI没有指定查找哪个寄存器或内存以查找返回值。代码无法设置返回值,调用代码可以获取任何返回值
因此,不需要,函数不必返回任何内容。假设构造函数可以返回某些内容,那么下面的函数调用就有问题了:
class Object{
public:
bool Object(){ ... };
...
}
SomeFun(Object obj){ ... }
SomeFun(Object());
// Ha! SomeFun jokes on an error about a non-Object argument(of type bool), returned
// by the anonymous temporary Object()
防止构造函数返回,方便使用匿名临时性,以及更多的C++特性。如果没有这样的规则,无害的陈述可能会变得模棱两可:
Object obj(Object());
// How does the variable obj decide which constructor to call,
// based on its argument type?
//
// Does it call: bool Object::Object(Object&) or
// Object::Object(bool)(if it exists)?
构造函数能够返回一个值,使对象的创建复杂化——在没有任意返回值的情况下,使用单一的明确类型、类名可以避免此类问题
读者能提出一些C++例句是否被这种规则的缺失所阻碍的例子?p> 构造函数隐式返回类本身的实例。如果它被设计为返回一些东西,而程序员返回的东西与类本身完全不同,那么这将是矛盾的。基本上,语法会令人困惑。构造函数可能是一个坏名字。它实际上是预构造对象的初始值设定项。最简单的方法是在不使用C++构造函数的情况下构造等价结构的伪示例。 与建设者
struct X {
int a;
X() {
a = -5;
}
};
int main() {
X* x1 = new X(); // X created as a "reference object".
X x2; // X created as a "value object" on the stack.
return x1->a - x2.a;
}
struct X {
int a;
void initialize() {
a = -5;
}
static X* create() {
X* res = (X*)malloc(sizeof(X));
res->initialize();
return res;
}
};
int main() {
X* x1 = X::create(); // New constructed heap-allocated X
X x2; // Stack-allocated X
x2.initialize(); // Manually initialized
return x1->a - x2.a;
}
没有构造器
struct X {
int a;
X() {
a = -5;
}
};
int main() {
X* x1 = new X(); // X created as a "reference object".
X x2; // X created as a "value object" on the stack.
return x1->a - x2.a;
}
struct X {
int a;
void initialize() {
a = -5;
}
static X* create() {
X* res = (X*)malloc(sizeof(X));
res->initialize();
return res;
}
};
int main() {
X* x1 = X::create(); // New constructed heap-allocated X
X x2; // Stack-allocated X
x2.initialize(); // Manually initialized
return x1->a - x2.a;
}
现在,如果您设想第二个示例中的X::initialize
要返回,比如一个bool
表示成功或失败,那么您将遇到一个问题。在main()
中,漫不经心的程序员可能会导致未正确初始化的X
,从而导致未定义的行为(通常是难以调试的崩溃,在生产之前可能无法发现)
这是建造师变得特别的核心原因之一。退出构造函数的唯一两种方法是通过正常完成或通过异常,然后必须由调用方处理(或向上传递堆栈)。在任何情况下,都不能以未初始化的对象结束
顺便说一句,未初始化的对象是C语言中最常见的错误原因之一,它对程序员没有任何帮助。出于好奇,什么时候让构造器返回它正在构造的对象以外的任何东西会有用甚至有意义?好吧,它会返回新创建的对象。谁说构造器是函数?(除了在“特殊成员函数”的标准部分中描述的事实之外),构造函数甚至不会返回
void
(如果有意义的话)。它们没有返回类型。@DavidHammen这只是语法上的一个区别。将函数的返回类型声明为void
具有相同的含义。这只是语法上的差异吗?构造函数是一个void函数,在这个意义上,return语句必须是return构造函数中的代码>。但是,通过使构造函数不可调用并保留