为什么我所有的“this”指针都是相同的值?

问题描述 投票:0回答:1

我正在编写以下代码片段:

#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;
}

我正在使用

g++ main.cpp
编译代码。当我执行编译的二进制文件时,我得到:

0x7ffebb8f8cab
0x7ffebb8f8cab
0x7ffebb8f8cab
0x7ffebb8f8cab
0x7ffebb8f8cab
0x7ffebb8f8cab
0x7ffebb8f8cab
0x7ffebb8f8cab
0x7ffebb8f8cab
0x7ffebb8f8cab

我的问题是为什么所有

this
指针都是相同的?如果我创建同一类的 10 个不同对象,则应该有 10 个不同的
this
指针。对吗?

据我了解,我的代码当前正在使用相同对象的引用来填充向量

v
。然而,我想要的是 10 个不同的
myclass
对象。我怎样才能得到这个?此代码是一个较大项目的一部分,该项目在
new
delete
方面存在一些问题。所以我无法使用该 API。我做错了什么以及如何解决这个问题?

c++ pointers this
1个回答
41
投票

如评论中所述,您将看到临时对象的

this
指针,然后将临时对象复制到向量中。由于临时是temporary,您的系统在每次循环迭代中重用相同的内存位置。

但是,如果打印向量元素的

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;
}

输出:

0x7ff7bfe6f5a8
0x7ff7bfe6f5a8
0x7ff7bfe6f5a8
0x7ff7bfe6f5a8
0x7ff7bfe6f5a8
0x7ff7bfe6f5a8
0x7ff7bfe6f5a8
0x7ff7bfe6f5a8
0x7ff7bfe6f5a8
0x7ff7bfe6f5a8

0x600001f4c030
0x600001f4c031
0x600001f4c032
0x600001f4c033
0x600001f4c034
0x600001f4c035
0x600001f4c036
0x600001f4c037
0x600001f4c038
0x600001f4c039

emplace_back

的成员函数
std::vector
可用于在向量中就地构造对象。

在下面我们构造了 5 个临时变量,我们可以看到它们重用了相同的内存,然后我们使用

push_back
将它们放入向量中。

然后我们使用

emplace_back
直接在向量中构造五个对象。

我们可以看到创建对象时打印的内存地址和后面打印的内存地址是一样的。

注意:如果大小超过容量,向量可能会重新分配和移动其内容。为了避免这种情况,我为向量

v
保留了 10 的容量。

#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;
}

输出:

0x7ff7bf57b598
0x7ff7bf57b598
0x7ff7bf57b598
0x7ff7bf57b598
0x7ff7bf57b598
0x600002610035
0x600002610036
0x600002610037
0x600002610038
0x600002610039

0x600002610030
0x600002610031
0x600002610032
0x600002610033
0x600002610034
0x600002610035
0x600002610036
0x600002610037
0x600002610038
0x600002610039
© www.soinside.com 2019 - 2024. All rights reserved.