c++ - 在构造函数的主体中证明分配效率低下
问题描述
我在http://www.cs.technion.ac.il/users/yechiel/c++-faq/init-lists.html中读到
,使用初始化列表比在构造函数的主体中进行分配更有效,因为例如在Fred::Fred() { x_ = whatever; }
1) 导致创建一个单独的临时对象的表达式,并且这个临时对象被传递给 x_ 对象的赋值运算符。然后该临时对象在 ; 处被销毁。
2)成员对象将由其默认构造函数完全构造,例如,这可能会分配一些默认数量的内存或打开一些默认文件
赋值如何导致在构造函数中创建一些临时对象?这意味着构造函数会调用自己:无限递归调用
我制作了以下代码来验证在分配过程中创建了对象的副本,希望看到临时对象的额外创建和销毁,但我只能看到我正在创建的对象的创建和销毁main 当然没有无限递归调用。如何理解它以及如何修改代码以查看临时对象的创建和销毁?
#include<iostream>
using namespace std;
class Base
{
private:
int c_var;
public:
Base( )
{ c_var=10;
cout <<"Constructor called"<<endl;
cout << "Value is " << c_var<<endl;
}
~Base()
{
cout <<"Destructor called"<<endl;
}
};
int main()
{
Base il;
}
解决方案
赋值如何导致在构造函数中创建一些临时对象?这意味着构造函数会调用自己:无限递归调用
没有。文中谈到调用成员的构造函数。有了int
它并没有太大关系,但请考虑:
struct foo {
foo() {
/* construct a foo, with expensive instructions */
std::cout << "default constructor";
}
foo(int x) {
/* also construct a foo */
std::cout << "constructor";
}
};
struct bar_wrong {
foo f;
bar_wrong() {
f = foo(42);
}
};
在执行构造函数的主体之前初始化成员。因此,foo
成员bar_wrong
将首先被默认构造(这可能很昂贵),稍后会被正确的实例覆盖并创建 abar_wrong
将打印来自foo
s 构造函数的两个输出。
正确的方法是
struct bar_correct {
foo f;
bar_correct() : f(42) {}
};
因为这里foo
只是初始化。或者,您可以使用类内初始化程序:
struct bar_alternative {
foo f{42};
};
这里编译器生成的构造函数就足够了。它将使用类内初始化程序进行f
初始化42
。
推荐阅读
- reactjs - 为什么材质 UI 反应步进器没有标签焦点?
- ios - How do i know if a specific date is a month, or a week to an parent date?
- python - Changing a string to a float when doing web scraping Python
- javascript - 添加到愿望清单按钮在漂亮的照片脚本中不起作用
- git - Devops 管道 - 从其他 repo 签出代码:auth 错误
- email - Freemarker Loop to write tables
- angular9 - Angular 9 从源“http://localhost:4200”访问“xxxxxx.net/api”的 XMLHttpRequest 已被策略阻止
- mongodb - CosmosDB 中不同的唯一键和分区键
- java - How to get value from position adapter RecyclerView
- google-apps-script - Google表格脚本:删除基于复选框的范围