c++ - 参数化构造函数的调用是如何执行的?
问题描述
这段代码有友元函数和运算符重载,我得到的输出部分有意义,所以这里是代码,我没有得到的是构造函数如何具有浮点类型参数当在 中进行的调用带有对象参数时被调用。
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
...
解决方案
如果我做对了,您想知道为什么a(float f)
当您将 a 添加float
到a
.
所以,这是由隐式构造引起的,它的发生是因为有几件事:
- 您有一个以 a
float
作为参数的构造函数。 - 您有一个
operator+
重载,它需要两个a
.
因此,当您执行加法时,右侧变量是 a float
。由于您可以a
使用浮点数进行实例化,因此会调用构造函数来创建一个实例a
以将其添加到您的左侧实例中。然后你会得到两个副本,因为该operator+
函数需要两个a
by copy 实例。
一步一步的细分是这样的:
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
既然我解释了发生了什么,我想我也应该解释如何避免它。
如果出于某种原因,您不希望发生隐式构造,则可以执行以下两项操作之一:
float
使用关键字为带有参数的构造函数添加前缀explicit
,这意味着构造函数永远不会作为隐式转换或复制初始化的一部分被调用。它也将不再允许您将任何可以转换为 a 的参数float
隐式传递给它。- 声明并定义另一个
operator+
以 afloat
作为其右侧参数的函数。类似的东西friend a operator+(a x, float y)
。将调用此运算符而不是当前运算符,因为它不需要转换即可工作。
推荐阅读
- ruby-on-rails - 模型文件中的 Rails faker?
- c# - 将 webpack 与 Web 表单结合使用
- java - 使用 SOAP 连接到服务器时出错
- swift - 将 iOS 应用程序与 AWS EC2 服务器连接时出现问题
- bash - 为什么 rm -rf $DIR 从 bash 脚本运行时不删除目录
- c++ - 如何通过函数的 void 指针参数传递 int 值并将其转换回 int 值?
- javascript - 事件和事件处理是 JavaScript 语言本身的固有部分吗?
- sql-server - 将变量传递给另一个案例
- python - 为什么我的 KernelReg.bw 为负数?它不应该是积极的吗?我的代码有什么问题?
- c# - 仅当执行参数相同时,如何阻止 Web 应用程序中的进程?