让我们添加一个拷贝构造函数(并使用一个较小的测试用例,以减少冗长),看看会发生什么...
#include <iostream>
#include <string>
#include <vector>
class Test
{
public:
std::string name;
Test(){};
Test(std::string name) : name(name) {
std::cout << "New " << name << '\n';
}
Test(const Test& other) : name("Copy of " + other.name) {
std::cout << "Copied " << other.name << '\n';
}
~Test() {std::cout << "Destroy " << name << '\n';}
};
std::vector<Test> test {Test("Original") };
int main()
{
std::cout << "Loop:\n";
for (auto i : test)
std::cout << "This is " << i.name << '\n';
std::cout << "Clear\n";
test.clear();
}
这会产生:
New Original
Copied Original
Destroy Original
Loop:
Copied Copy of Original
This is Copy of Copy of Original
Destroy Copy of Copy of Original
Clear
Destroy Copy of Original
说明:
New Original -- The object in the initialzer list
Copied Original -- Here it gets copied into the vector
Destroy Original -- The original is destroyed along with the initializer list
Loop:
Copied Copy of Original -- Copied into the loop variable
This is Copy of Copy of Original -- Printing in the loop
Destroy Copy of Copy of Original -- The temporary loop object is destroyed
Clear
Destroy Copy of Original -- Clearing the vector
如果您循环引用,
i
将指向向量内部的对象,而不是其副本-只需更改一行即可。
for (auto& i : test)
将输出更改为
New Original
Copied Original
Destroy Original
Loop:
This is Copy of Original
Clear
Destroy Copy of Original
通过直接在向量中创建对象,您可以摆脱进一步的复制:
int main()
{
std::vector<Test> test;
test.emplace_back("Original");
std::cout << "Loop:\n";
for (auto& i : test)
std::cout << "This is " << i.name << '\n';
std::cout << "Clear\n";
test.clear();
}
输出:
Original
Loop:
This is Original
Clear
Destroy Original
this
的值,因为编译器可以生成并使用复制或移动析构函数。拥有this
是唯一可靠的方法来知道实际被销毁的对象是什么。 - Serge Ballesta