返回信息流在学`class`的时候看到书上说构造函数没有返回类型。
上网搜了一下,发现的确如此。网上的说法是“构造函数不需要返回值,也就没有返回值”。
自己试验了一下,发现也是如此。如果要指定一个`void`或其它类型(包括这个`class`本身),编译器就会报错。
那么我有了新的问题:如果一个构造函数没有返回值,那么在调用构造函数的时候(如下面的代码),`func(A)`接收的参数又是什么呢?难道不正是`A(...)`返回的临时对象吗?
```C++
class A{...};
A::A(...){...}
void func(A obj){...}
//main(){
func(A(...));
```
再比如说,我尝试用`typeid`获取构造函数的返回类型(如果它存在的话):
```C++
cout<<typeid(A(...)).name()<<endl;
```
得到的输出也与`typeid(A).name()`一致。
我又写了这样一句代码:
```C++
int a=A(...);
```
编译器给出报错信息`[Error] cannot convert 'A' to 'int' in initialization`。
**这两个事实说明,`A(...)`在代码中表现出的类型确实是`A`。**
那么只剩下一种可能:`A(...)`不是构造函数的返回值,而是别的什么东西。
那它是什么呢?还望各位大神指点迷津。
这是一条镜像帖。来源:北邮人论坛 / cpp / #102805同步于 2023/8/15
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
【问题】关于“构造函数”与“返回值”
cppHusky
2023/8/15镜像同步21 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
【 在 cppHusky 的大作中提到: 】
: [md]
: 在学`class`的时候看到书上说构造函数没有返回类型。
: 上网搜了一下,发现的确如此。网上的说法是“构造函数不需要返回值,也就没有返回值”。
: ...................
示例代码:
``` c++
#include <iostream>
class Foo {
private:
int a;
int b;
public:
Foo(int a, int b) {
this->a = a;
this->b = b;
}
int get_a() { return this->a; }
};
void bar(Foo foo) {
std::cout << "foo.a = " << foo.get_a() << std::endl;
}
int main()
{
bar(Foo(1, 2));
return 0;
}
```
编译后反编译得到 main 函数的汇编:
```
00000000004011f5 <main>:
4011f5: 55 push %rbp
4011f6: 48 89 e5 mov %rsp,%rbp
4011f9: 48 83 ec 10 sub $0x10,%rsp
4011fd: 48 8d 45 f0 lea -0x10(%rbp),%rax
401201: ba 02 00 00 00 mov $0x2,%edx
401206: be 01 00 00 00 mov $0x1,%esi
40120b: 48 89 c7 mov %rax,%rdi
40120e: e8 65 00 00 00 call 401278 <_ZN3FooC1Eii>
401213: 48 8b 45 f0 mov -0x10(%rbp),%rax
401217: 48 89 c7 mov %rax,%rdi
40121a: e8 8e ff ff ff call 4011ad <_Z3bar3Foo>
40121f: b8 00 00 00 00 mov $0x0,%eax
401224: c9 leave
401225: c3 ret
```
`_ZN3FooC1Eii` 是定义的构造函数,汇编为:
```
0000000000401278 <_ZN3FooC1Eii>:
401278: 55 push %rbp
401279: 48 89 e5 mov %rsp,%rbp
40127c: 48 89 7d f8 mov %rdi,-0x8(%rbp)
401280: 89 75 f4 mov %esi,-0xc(%rbp)
401283: 89 55 f0 mov %edx,-0x10(%rbp)
401286: 48 8b 45 f8 mov -0x8(%rbp),%rax
40128a: 8b 55 f4 mov -0xc(%rbp),%edx
40128d: 89 10 mov %edx,(%rax)
40128f: 48 8b 45 f8 mov -0x8(%rbp),%rax
401293: 8b 55 f0 mov -0x10(%rbp),%edx
401296: 89 50 04 mov %edx,0x4(%rax)
401299: 5d pop %rbp
40129a: c3 ret
40129b: 90 nop
```
从函数调用上你会发现,构造函数实际上有三个参数,第一个参数其实是对象变量,也就是 this 指针,第二、三个参数才是上述代码中的两个参数。
考考楼主,下面程序中func接收到的指针,难道是“还没有返回,就已经存在了”的值?
#include <cstdio>
class A;
void func(A *a) {
printf("Entering func... a == %p\n", a);
}
class A {
public:
A() {
printf("Entering A()... this = %p\n", this);
func(this);
printf("Leaving A()... this = %p\n", this);
}
};
int main() {
A my_a;
}
【 在 nuanyangyang 的大作中提到: 】
: 考考楼主,下面程序中func接收到的指针,难道是“还没有返回,就已经存在了”的值?
: [code=cpp]
: #include <cstdio>
: ...................
哦,也就是说,这个对象是在构造函数调用之初就创建的,构造函数的作用只是给成员变量一组初始值。`A()`作为`func(A*)`参数的时候,传入的是这个对象本身,而非`A()`的“返回值”。
这样理解对吗?