我正在为即将到来的C ++考试做准备,并且遇到了关于类和构造函数的问题:
Fraction类有多少个构造函数?“
class Fraction { //... public: Fraction(int numerator = 0, int denominator = 1); //... };
我认为这只是一个,但他们建议有三个:
Fraction();
Fraction(n);
Fraction(n, d);
或换句话说:
具有默认值的函数是否为重载函数?
答案 0 :(得分:55)
只有一个构造函数对应于已发布的声明,而不是三个重载。
电话
Fraction();
Fraction(n);
相当于:
Fraction(0, 1);
Fraction(n, 1);
另一种说服自己只有一个与声明对应的构造函数的方法是你只需要定义一个构造函数,而不是三个。
关于默认参数的C ++ 11标准部分包含:
8.3.6默认参数
1如果在 parameter-declaration 中指定了 initializer-clause ,则 initializer-clause 将用作默认参数。默认参数将用于缺少尾随参数的调用中。
2 [示例:声明
void point(int = 3, int = 4);
声明一个可以使用\ type
int
的零个,一个或两个参数调用的函数。它可以通过以下任何方式调用:point(1,2); point(1); point();
最后两次调用分别相当于
point(1,4)
和point(3,4)
。 -end example ]
现在是主要问题。
Fraction类有多少个构造函数?
如果框架问题的人想要包含移动构造函数和复制构造函数(由编译器隐式生成除非明确删除),在构造函数集中,那么答案是三 。在这种情况下,问题是一个棘手的问题。
答案 1 :(得分:27)
具有默认值的函数是否为重载函数?
没有。重载看起来像
Fraction();
Fraction(int numerator);
Fraction(int numerator, int denominator);
并且每个都有自己的实现(定义),而具有默认参数的函数只有一个实现。
我认为这只是一个,但他们建议有3个:......
“Fraction类有多少个构造函数?”
给定代码段的明确答案为 3 (单词 3 )。
有一个专门的构造函数(提供三种调用变体),如果你没有delete
,编译器会自动生成一个复制和移动构造函数,或者提供一个自定义的实现:
Fraction(int numerator = 0, int denominator = 1); // (1)
// Redundant, just for demonstration:
Fraction(const Fraction& rhs) = default; // (2)
Fraction(Fraction&& rhs) = default; // (3)
所以对于这样的考试,如果你会回答
该类有一个构造函数
反正这是错的。如果你回答
该类有三个构造函数(正如您所写,这是已接受的答案)
你需要深入解释,为什么这么认为(如上所述) 在任何口语考试中,我都会要求你准备好原因,所以我会在学徒考试中做。
答案 2 :(得分:18)
您的问题的答案与这三个后续问题有关:
显式定义只是一个构造函数;无论调用是否显式提供0,1或2个参数,编译器都将插入一个三参数调用。
在pre- 11中没有移动构造函数,在' 11中有两个隐式构造函数定义,Fraction(const Fraction &) noexcept
和Fraction(Fraction &&) noexcept
,检查可访问的cppreference ,在' 14中有一个隐含定义的移动构造函数更改的规则。
不幸的是,你得到的问题看上去却非常技术性;我希望你的班级不要过分简化C ++,这是学习它的最糟糕方式。
答案 3 :(得分:6)
你只有一个构造函数的声明 另一方面:
如果为同一范围内的单个名称指定了两个或更多不同的声明,则说该名称已过载
因此,我不会在这里使用术语重载。
答案 4 :(得分:-4)
这种函数定义定义了一个函数,但有两个额外的调用语法。在获取函数指针或将模板函数参数与重载函数匹配时,细微差别变得明显:在这种情况下,您只有一个带有完整参数列表的函数作为可用的重载类型。
现在棘手的是我们在这里谈论一个构造函数,并且构造函数不会像普通函数那样使用相同类型的重载解析,并且出于所有目的,除了语法之外不能访问它。特别是,此定义 分别作为默认构造函数进行计数。它也可以作为int的转换构造函数单独计算,可以用作((分数)3)。
因此,出于所有实际目的,它在构造函数类别中创建了三个不同的语法实体。与普通函数相反,没有函数上下文,其中重载解析会暴露三个实际函数签名和三个仅仅是语法调用约定之间的差异。
这对于书面测试来说不是一个好问题。这真的适合口语考试,因为有很多细微之处,正式答案(如果有的话)和正式错误答案之间的差异不太可能与实际知识和技能有很好的关联,以及任何答案背后的推理比答案本身更重要。
答案 5 :(得分:-5)
因为它取决于您传递的参数:
Fraction() --> Fraction(0,1)
Fraction(n)---> Fraction(n,1)
Fraction(n,m)
所以它给了3个构造函数。这里没有超载。
答案 6 :(得分:-6)
您可以使用在上面的类中声明为int的单个构造函数以三种不同的方式创建Fraction对象。构造函数具有默认参数。如果你没有传递任何参数,它会假定参数的相应值。
Fraction a;
//分子将为0,分母将为1
Fraction a(10);
//分子为10,分母为1
Fraction a(10, 20);
//分子将为10,分母将为20