参数化构造函数的调用是如何执行的?

How the invoking of parameterized constructor is executed?

提问人:Aniket Saha 提问时间:11/25/2019 最后编辑:Roberto CaboniAniket Saha 更新时间:11/25/2019 访问量:46

问:

有一段代码具有朋友函数和运算符重载,我得到的输出部分有意义,所以这是代码,我没有得到的是,当在 中使用对象参数进行调用时,如何调用具有浮点类型参数的构造函数。

class a
{
    public:
        a():n(3),d(2)
        {
            cout<<endl<<"default constructor called";
        }
        a(float f):n(f),d(1)
        {
            cout<<endl<<"type casting constructor called";
        }
        a(const a &f)
        {
            cout<<endl<<"copy constructor called";
        }
        friend a operator+( a x, a y);
};
a operator+(a x, a y)
{
    return x;
}

这是主要部分

int main()
{
    a f1;

    float f=1.5;

    f1+f;

}

问题究竟是如何调用参数化构造函数或类型转换构造函数的?

Output:
default constructor called


type casting constructor called
copy constructor called
copy constructor called

...
C++ 运算符重载 复制 默认构造 友善函数

评论

0赞 AndyG 11/25/2019
将浮点型构造函数标记为显式,然后查看会发生什么情况
0赞 Chris Dodd 11/25/2019
代码无法按编写的方式编译,因为没有 或 的声明。nd

答:

0赞 micka190 11/25/2019 #1

如果我做对了,你想知道为什么当你将一个 添加到现有的实例时会调用构造函数。a(float f)floata

所以,这是由隐式构造引起的,它的发生是因为以下几件事:

  1. 你有一个构造函数,它把一个作为参数。float
  2. 您有一个重载,它需要两个实例。operator+a

因此,当您执行加法时,右侧变量是 .由于您可以使用浮点数进行实例化,因此会调用构造函数来创建一个实例,以将其添加到左侧实例中。然后,您将获得两个副本,因为该函数采用 by copy 的两个实例。floataaoperator+a

分步细分如下:

  • a f1; // Outputs "default constructor called"
  • f1 + f; // "f" is a float, so we can construct an instance of "a".
  • f1 + a(f); // Outputs "type casting constructor called"
  • operator+(a x, a y); // Takes two copies, so outputs "copy constructor called" twice

既然我解释了发生了什么,我想我也应该解释如何避免它。

如果出于某种原因,您不希望发生隐式构造,则可以执行以下两项操作之一:

  • 在采用参数的构造函数前面加上关键字,这意味着该构造函数永远不会作为隐式转换或复制初始化的一部分被调用。它也将不再允许您将任何可以隐式转换为 a 的参数传递给它。floatexplicitfloat
  • 声明并定义另一个函数,该函数将 a 作为其右侧参数。类似 .将调用此运算符而不是当前运算符,因为它不需要转换即可工作。operator+floatfriend a operator+(a x, float y)