C++ 为什么回岗很重要?

C++ 为什么回岗很重要?,c++,c++11,C++,C++11,为什么有这么多的设计人员呼叫?我看到: (1) 构造临时对象temp1 (2) 自毁temp1 (3) 构造临时对象temp2 (4) 自毁temp2 然后它被称为temp1和temp2的复制构造函数或移动构造函数。所以,(5)和(6)是清楚的。但是(7)呢?让我们稍微扩展一下您的结构: (1)Constructor (2)Destructor (3)Constructor (4)Destructor (5)Destructor (6)Destructor (7)Destructor 现在,输

为什么有这么多的设计人员呼叫?我看到:

(1) 构造临时对象temp1

(2) 自毁temp1

(3) 构造临时对象temp2

(4) 自毁temp2


然后它被称为temp1和temp2的复制构造函数或移动构造函数。所以,(5)和(6)是清楚的。但是(7)呢?让我们稍微扩展一下您的结构:

(1)Constructor
(2)Destructor
(3)Constructor
(4)Destructor
(5)Destructor
(6)Destructor
(7)Destructor
现在,输出看起来更加完整:

vec.push_back(T()); // 1
std::cout << "--- --- ---\n";

vec.push_back(T()); // 2
std::cout << "--- --- ---\n";
第一组:

Constructor
Move Constructor
Destructor
--- --- ---
Constructor
Move Constructor
Copy Constructor
Destructor
Destructor
--- --- ---
Destructor
Destructor
对应于第一个
push_back
呼叫:

Constructor
Move Constructor
Destructor
Constructor
Move Constructor
Copy Constructor
Destructor
Destructor
输出可能很容易解密:

vec.push_back(T()); // 1
第二组:

Constructor // Create a temporary
Move Constructor // Move a temporary into the internal vector storage
Destructor // Destroy a temporary
对应于第二次
push_back
呼叫:

Constructor
Move Constructor
Destructor
Constructor
Move Constructor
Copy Constructor
Destructor
Destructor
还有一点复杂:

vec.push_back(T()); // 2
这里您应该记住,vector类在内部分配内存,然后对其进行管理,为所有元素提供足够的空间。因此,如果添加更多元素,就会发生新的分配,旧元素会被复制或移动到新存储中

在已知大小的情况下,您可以使用
reserve
方法,该方法仅为特定数量的元素保留足够的内存。它允许在向向量中添加新元素时避免不必要的内存重新分配以及在这些重新分配期间复制或移动元素(至少在不超过保留大小之前)

第三组:

Constructor // create a temporary
Move Constructor // move it into the newly allocated vector storage
Copy Constructor // copy previously created element into the new storage
Destructor // destroy old storage
Destructor // destroy temporary

对应于程序末尾的vector
vec
析构函数调用。

让我们稍微扩展一下您的结构:

(1)Constructor
(2)Destructor
(3)Constructor
(4)Destructor
(5)Destructor
(6)Destructor
(7)Destructor
现在,输出看起来更加完整:

vec.push_back(T()); // 1
std::cout << "--- --- ---\n";

vec.push_back(T()); // 2
std::cout << "--- --- ---\n";
第一组:

Constructor
Move Constructor
Destructor
--- --- ---
Constructor
Move Constructor
Copy Constructor
Destructor
Destructor
--- --- ---
Destructor
Destructor
对应于第一个
push_back
呼叫:

Constructor
Move Constructor
Destructor
Constructor
Move Constructor
Copy Constructor
Destructor
Destructor
输出可能很容易解密:

vec.push_back(T()); // 1
第二组:

Constructor // Create a temporary
Move Constructor // Move a temporary into the internal vector storage
Destructor // Destroy a temporary
对应于第二次
push_back
呼叫:

Constructor
Move Constructor
Destructor
Constructor
Move Constructor
Copy Constructor
Destructor
Destructor
更复杂一点:

vec.push_back(T()); // 2
这里您应该记住,vector类在内部分配内存,然后对其进行管理,为所有元素提供足够的空间。因此,如果添加更多元素,就会发生新的分配,旧元素会被复制或移动到新存储中

在已知大小的情况下,您可以使用
reserve
方法,该方法仅为特定数量的元素保留足够的内存。它允许在向向量中添加新元素时避免不必要的内存重新分配以及在这些重新分配期间复制或移动元素(至少在不超过保留大小之前)

第三组:

Constructor // create a temporary
Move Constructor // move it into the newly allocated vector storage
Copy Constructor // copy previously created element into the new storage
Destructor // destroy old storage
Destructor // destroy temporary
对应于程序末尾的vector
vec
析构函数调用

对于“仅移动”类型(如std::unique\u ptr),emplace\u back很重要

这是错误的,过于简单化了。并非所有容器都是平等创建的。对于向量示例,如果我们使用
reserve
实现可以执行移动赋值而不是构造,从而省去了复制/无关析构函数:

Destructor
Destructor
对于一组:

Constructor
Constructor
---
Destructor
Destructor
std::set s;
s、 炮位(1);
s、 炮位(1);
我们得到相同的输出。为什么呢?一个集合理论上应该只构造一个对象,因为集合是唯一的,对吗?实际上,典型的实现构造一个临时节点来执行比较,即使它从未进入容器,也会考虑额外的构造/析构函数

对于“仅移动”类型(如std::unique\u ptr),emplace\u back很重要

这是错误的,过于简单化了。并非所有容器都是平等创建的。对于向量示例,如果我们使用
reserve
实现可以执行移动赋值而不是构造,从而省去了复制/无关析构函数:

Destructor
Destructor
对于一组:

Constructor
Constructor
---
Destructor
Destructor
std::set s;
s、 炮位(1);
s、 炮位(1);

我们得到相同的输出。为什么呢?一个集合理论上应该只构造一个对象,因为集合是唯一的,对吗?实际上,典型的实现构造一个临时节点来执行比较,即使它从未进入容器,也会考虑额外的构造/析构函数

还应提供一个副本构造函数;这可能会有启发性。此外,它还可以帮助在调用前、调用后和调用之间打印一些内容,这样你就可以知道这些构造函数和析构函数在什么时候响应什么动作。你的意思是要调用emplace_一次并将其推回一次吗?看不出调用push_back两次的意义,它与您的标题不匹配。当vector需要增加其存储时,它会分配新的(更大的)内存块,将原始元素复制或移动到新存储,然后销毁原始元素并释放旧内存。额外的析构函数调用很可能来自于此。调用
reserve
first?
emplace\u back
对于“仅移动”类型(如
std::unique\u ptr
)很重要。同时插入副本构造函数;这可能会有启发性。此外,它还可以帮助在调用前、调用后和调用之间打印一些内容,这样你就可以知道这些构造函数和析构函数在什么时候响应什么动作。你的意思是要调用emplace_一次并将其推回一次吗?看不出调用push_back两次的意义,它与您的标题不匹配。当vector需要增加其存储时,它会分配新的(更大的)内存块,将原始元素复制或移动到新存储,然后销毁原始元素并释放旧内存。额外的析构函数调用可能来自于此。首先调用
reserve
emplace\u back
对于“仅移动”类型(如
std::unique\u ptr
)很重要。这与问题有何关系?如果你要回答评论,请在评论部分回答,不要回答。@Revolver\u Ocelot我很抱歉,因为我在回答中引用了一条评论,它突然不再回答问题。我很高兴你们来这里监督事情。这和问题有什么关系?如果你要回答评论,请在评论部分回答,不要回答。@Revolver\u Ocelot我很抱歉,因为我在回答中引用了一条评论,它突然不再回答问题。我很高兴你来这里监督事情。这再次说明了n