假设我有一堂课
class Test{
public:
int x;
Test(const Test& obj){x=obj.x;}
};
为什么
Test object_name(Test random_name);
运行,是否不需要其他对象作为参数?
像Test random_name(Test another_random(...))
一样,使它成为声明对象的永无止境的方式吗?
答案 0 :(得分:9)
此行:
Test object_name(Test random_name);
声明一个名为object_name
的函数,该函数将Test
作为参数并返回Test
。它没有声明对象。在另一个函数中声明这样的函数是完全合法的,它只是隐式extern
。
答案 1 :(得分:6)
用Test
这样的PoD代替int
,您会看到发生了什么
Test object_name(Test random_name); //1
int object_name(int random_name); //2
您可以看到第二条语句是一个函数声明,该函数声明以int
作为参数并返回int
。
这是由于CPP中与歧义解决有关的一条众所周知的规则。
从CPP工作草案(N4713):
9.8歧义度解析度[stmt.ambig]
1语法中涉及表达式声明和声明有歧义:具有函数样式显式类型转换的表达式声明,因为其最左边的子表达式可能与第一个声明符以a开头的声明没有区别。 (。 在这种情况下,声明是声明。
2 [注意:如果该语句不能在语法上成为声明,则不存在歧义,因此该规则不适用。可能需要检查整个语句以确定是否是这种情况。
答案 2 :(得分:0)
这是一个重构的版本,应该有助于解释发生了什么。我添加了另一个构造函数来说明发生了什么。
#include <iostream>
using namespace std;
class Test{
public:
int x = 27;
Test(const int y) : x(y) { cout << "ctor-1" << endl; }
~Test() {}
Test(const Test& obj) : x(obj.x) { cout << "ctor-2" << endl; }
operator int() const { return x; }
};
int main()
{
cout << "Creating function declaration" << endl;
Test object_name(Test random_name);
// This works fine
cout << "Creating alpha" << endl;
Test alpha(4);
cout << "Calling `object_name`" << endl;
cout << object_name(alpha) << endl;
// This fails because object_name is a function.
// cout << object_name.x << endl;
return 0;
}
Test object_name(Test random_name)
{
cout << "Creating another Test within `object_name`." << endl;
return Test(random_name.x + 13);
}
在这里,我们看到第一个构造函数被调用了两次:一次是为alpha
,另一次是在object_name
中。当我们调用object_name
时,将调用第二个构造函数,该构造函数接受按值传递的参数。
Creating function declaration
Creating alpha
ctor-1
Calling `object_name`
ctor-2
Creating another Test within `object_name`.
ctor-1
17