Set*_*etu 41 c++ pointers this
我正在研究以下代码片段:
#include <iostream>
#include <vector>
class myclass
{
public:
myclass()
{
std::cout << this << std::endl;
}
};
int main()
{
std::vector<myclass> v;
for(uint32_t i = 0; i < 10; i++)
v.push_back(myclass());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我正在使用 编译代码g++ main.cpp。当我执行编译的二进制文件时,我得到:
0x7ffebb8f8cab
0x7ffebb8f8cab
0x7ffebb8f8cab
0x7ffebb8f8cab
0x7ffebb8f8cab
0x7ffebb8f8cab
0x7ffebb8f8cab
0x7ffebb8f8cab
0x7ffebb8f8cab
0x7ffebb8f8cab
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么所有的this指针都是相同的?如果我创建同一类的 10 个不同对象,则应该有 10 个不同的this指针。正确的?
据我了解,我的代码当前正在使用相同对象的引用来填充向量v。然而,我想要的是 10 个不同的对象myclass。我怎样才能得到这个?此代码是一个较大项目的一部分,该项目在new和方面存在一些问题delete。所以我无法使用该 API。我做错了什么以及如何解决这个问题?
Chr*_*ris 52
正如注释中所述,您将看到this临时指针,然后将临时指针复制到向量中。由于临时是临时的,您的系统在每次循环迭代中重用相同的内存位置。
但是,如果打印this向量元素的指针,您会注意到它们被放置在连续的内存位置,就像您对向量所期望的那样。
#include <iostream>
#include <vector>
struct myclass {
myclass() {
std::cout << this << std::endl;
}
void print() const {
std::cout << this << std::endl;
}
};
int main() {
std::vector<myclass> v;
for (uint32_t i = 0; i < 10; i++)
v.push_back(myclass());
std::cout << "\n";
for (auto &x : v)
x.print();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
#include <iostream>
#include <vector>
struct myclass {
myclass() {
std::cout << this << std::endl;
}
void print() const {
std::cout << this << std::endl;
}
};
int main() {
std::vector<myclass> v;
for (uint32_t i = 0; i < 10; i++)
v.push_back(myclass());
std::cout << "\n";
for (auto &x : v)
x.print();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
的emplace_back成员函数std::vector可用于在向量中就地构造对象。
下面我们构造 5 个临时变量,我们可以看到它们重用了相同的内存,然后我们将push_back它们放置在向量中。
然后我们emplace_back直接在向量中构造五个对象。
可以看到,对象创建时打印的内存地址和后面打印的内存地址是一样的。
注意:如果大小超过容量,向量可能会重新分配和移动其内容。为了避免这种情况,我为向量保留了 10 的容量v。
#include <iostream>
#include <vector>
struct myclass {
myclass() {
std::cout << this << std::endl;
}
void print() const {
std::cout << this << std::endl;
}
};
int main() {
std::vector<myclass> v;
v.reserve(10);
for (uint32_t i = 0; i < 5; i++)
v.push_back(myclass());
for (uint32_t i = 0; i < 5; i++)
v.emplace_back();
std::cout << "\n";
for (auto &x : v)
x.print();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
0x7ff7bfe6f5a8
0x7ff7bfe6f5a8
0x7ff7bfe6f5a8
0x7ff7bfe6f5a8
0x7ff7bfe6f5a8
0x7ff7bfe6f5a8
0x7ff7bfe6f5a8
0x7ff7bfe6f5a8
0x7ff7bfe6f5a8
0x7ff7bfe6f5a8
0x600001f4c030
0x600001f4c031
0x600001f4c032
0x600001f4c033
0x600001f4c034
0x600001f4c035
0x600001f4c036
0x600001f4c037
0x600001f4c038
0x600001f4c039
Run Code Online (Sandbox Code Playgroud)