1. c++临时对象的引入 直接主题,上代码,
#include
class cls
{
public:
int a;
cls(int i)
{
a = i;
}cls()
{
cls(0);
}void show()
{
std::cout << "a = " << a << std::endl;
}
};
int main(void)
{
cls c;
c.show();
return 0;
}
程序想要实现的功能很简单:定义对象c的时候会编译器会去调用无参构造函数cls(),在cls()中以0作为参数去调用有参构造函数cls(int i),达到将成员变量a设置为0的目的。这是c++代码复用的思想,挺好,看运行结果:
文章图片
显然,打印出来的对象c的成员变量a并没有得到初始化。为什么?这就是临时对象捣的鬼。
2. 临时对象 在c++中,直接调用(代码上手动去调用而非编译器自己调用)构造函数将会产生一个临时对象,写几句代码验证临时对象的存在:
class cls
{
public:
int a;
cls(int i)
{
a = i;
std::cout << "cls(int i)" << std::endl;
}cls()
{
a = 0;
std::cout << "cls()" << std::endl;
}cls(const cls& m)//拷贝构造函数
{
std::cout << "cls(const cls& m)" << std::endl;
}void show()
{
std::cout << "a = " << a << std::endl;
}~cls()
{
std::cout << "~cls()" << std::endl;
}
};
int main(void)
{
cls(5).show();
//手动调用带参构造函数return 0;
}
运行结果:
文章图片
还能通过cls(5)去调用成员函数:
cls(5).show();
运行结果:
文章图片
show()的调用便是通过临时对象,临时对象没有对象名,它的生命周期只有一条语句(手动调用构造函数)的时间,作用域也只在这条语句间。
注意,临时对象并非好东西,它是c++程序中很多BUG来源之一,c++编译器会在不影响程序最终执行效果的前提下,尽量减少临时对象的产生。
代码验证:
int main(void)
{
//cls(5).show();
cls c1 = cls(6);
return 0;
}
程序中,cls(6)很明显会产生一个临时对象,并将该临时对象赋值给c1类。这里的赋值操作自然会调用到拷贝构造函数,所以猜测程序的运行结果为:
cls(int i)//cls(6)所致
cls(const cls& m)//=所致
~cls()//临时对象销毁所致
~cls()//c1对象销毁所致
实际运行结果:
文章图片
若依上面我猜测的程序执行流程运行程序,可见c1对象的产生需要经过两个构造函数:带参构造函数(临时对象调用)和拷贝构造函数(赋值类对象用),比起构造函数一次调用,显然效率低下得多,特别是在构造函数需要实现较多逻辑功能的时候。所以编译器做了优化,摈弃了临时对象的产生。优化后的代码应为:
源代码:cls c1 = cls(6);
编译器优化后:cls c1 = 6;
所以运行结果如上图所示。
【C/C++编程|c++类中的临时对象】回到一开始的问题,类中
cls()
{
cls(0);
}
事实上,cls(0)会生成一个临时对象,而0是初始化这个临时对象的。该行代码执行过后,临时对象便被销毁,所以不能实现程序预先的目的。在实际中,若确实要实现代码复用的功能,可以写成:
class cls
{
public:
int a;
void init(int b)
{
a = b;
}cls(int i)
{
init(i);
std::cout << "cls(int i)" << std::endl;
}cls()
{
init(a);
std::cout << "cls()" << std::endl;
}cls(const cls& m)//拷贝构造函数
{
std::cout << "cls(const cls& m)" << std::endl;
}void show()
{
std::cout << "a = " << a << std::endl;
}~cls()
{
std::cout << "~cls()" << std::endl;
}
};
这样就可以避免临时对象的产生了。
推荐阅读
- c|c 是一种编译型编程语言,我写了一门编程语言,你也可以!
- C/C++|C For Linux之内存访问-内存简介
- java|java c s聊天程序_基于C/S模式的简单聊天程序(附程序源码)
- C++|蓝桥杯之奇妙的数字
- 蓝桥杯|【第六届蓝桥杯】奇妙的数字
- c/c++|蓝桥杯 日期问题(枚举)
- Linux|Linux C/C++ 开发(学习笔记十三)(百万并发的服务器实现)
- C/C++读取SEGY文件(三)
- MQTT|MQTT初体验-百度智能云