这个类有多less构造函数?

我正在为即将到来的C ++考试做准备,并且遇到了关于类和构造函数的这个问题:

class级有多less构造函数?“

class Fraction { //... public: Fraction(int numerator = 0, int denominator = 1); //... }; 

我认为这只是一个,但他们build议有三个:

 Fraction(); Fraction(n); Fraction(n, d); 

换句话说:
是一个函数的默认值重载函数?

只有一个构造函数对应于发布的声明,而不是三个重载。

电话

 Fraction(); Fraction(n); 

相当于:

 Fraction(0, 1); Fraction(n, 1); 

还有一种方法可以说服你自己,只有一个与声明相对应的构造函数是你只需要定义一个构造函数而不是三个。

默认参数的C ++ 11标准部分有这样的:

8.3.6默认参数

1如果在参数声明中指定了初始化子句,则此初始化子句用作默认参数。 缺省参数将被用于追踪参数丢失的调用中。

2 [ 例如:声明

 void point(int = 3, int = 4); 

声明一个可以用\ inttypes的零个,一个或两个参数调用的函数。 可以用以下任何一种方式来调用它:

 point(1,2); point(1); point(); 

最后两个调用分别相当于point(1,4)point(3,4)– 例子 ]

现在的主要问题。

类Fraction有多less构造函数?

如果构造该问题的人想要包含移动构造函数和复制构造函数,这些构造函数由编译器隐式生成,除非明确删除,否则在构造函数集中, 答案是三 。 在这种情况下,这个问题是一个诡计的问题。

是一个函数的默认值重载函数?

不,重载看起来像

 Fraction(); Fraction(int numerator); Fraction(int numerator, int denominator); 

并有各自的实现(定义),而具有默认参数的函数只有一个实现。


我认为这只是一个,但他们build议有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) 

所以对于这样的考试,如果你会回答

这个类有一个构造函数

反正这是错误的。 如果你会回答

这个类有三个构造函数(就像你写的那个是被接受的答案一样)

你需要深入解释,为什么你这样认为(如上所述)。
在任何口语考试中,我都会要求你备份为什么,所以我会做一个学徒考试。

你的问题的答案是相对于这三个后续问题:

  1. 在C ++ 11,C ++ 11或C ++ 14之前?
  2. 隐式定义的构造函数是否算在内?
  3. 什么是会员? 不可复制成员的存在将删除隐式拷贝构造函数。

显式定义只是一个构造函数; 编译器将插入一个三参数调用,而不pipe调用是否显式提供0,1或2个参数。

在'11之前没有移动构造函数,在'11有两个隐式的构造函数定义, Fraction(const Fraction &) noexceptFraction(Fraction &&) noexcept ,检查可访问的cppreference ,在'14一个隐式定义的移动构造器的变化。

你得到的问题不幸的是看起来很天真,但技术性很强。 我希望你的class级不要过分简化C ++,这是学习它的最糟糕的方式。

你只有一个构造函数的声明。
另一方面:

如果在同一个作用域中为单个名称指定了两个或更多不同的声明,则该名称被称为重载

因此,我不会在这里使用重载的术语。

这种函数定义定义了一个函数,但定义了另外两个调用语法。 使用函数指针或将模板函数参数与重载函数进行匹配时,细微区别变得明显:在这种情况下,只有具有完整参数列表的函数作为可用的重载types。

现在棘手的是我们在这里讨论的是一个构造函数,而构造函数并不像普通函数那样使用同样的重载分辨率,并且出于所有目的,除了语法上之外,它们是不可访问的。 特别是,这个定义可以作为默认的构造函数单独计数。 它也可以作为int的转换构造函数单独计数,可以用作((Fraction)3)。

所以出于所有实际的目的,它在构造器类别中创build三个不同的语法实体。 而与普通函数不同的是,重载parsing不会暴露三个实际函数签名和三个语法调用约定之间的区别。

这不是一个书面testing的好问题。 这真的是一个口头考试的东西,因为有太多的微妙之处,正式的正确答案(如果有的话)和一个正式的错误答案之间的差异不可能与实际的知识和技能,任何答案背后的推理比答案本身更重要。

因为它取决于你传递的参数:

 Fraction() --> Fraction(0,1) Fraction(n)---> Fraction(n,1) Fraction(n,m) 

所以它给了3个构造函数。 这里没有超载。

你可以用三种不同的方式创buildFraction对象,使用上面的类声明的单个构造函数。 构造函数具有默认参数。 如果你没有通过任何论证,它就假定论证的相应值。

  1. Fraction a; //分子将是0,分母将是1

  2. Fraction a(10); //分子将是10,分母将是1

  3. Fraction a(10, 20); //分子将是10,分母将是20