两个对象似乎共享相同的地址

Two objects seem to share the same address

本文关键字:共享 地址 两个 对象      更新时间:2023-10-16

我正在使用Visual Studio Ultimate 2013 Preview,Windows 7。

我正在使用 CRTP 能够方便地将任何类型的对象推送到单独的向量中。

然而,结果很奇怪。你会看到我有两个类,AB 派生自Container。使用T* PushOne()将新实例推送到静态向量中,并返回其地址以供使用。

但是,出于某种原因,类 A 的第一个实例化对象和类B的第一个实例化对象似乎共享相同的地址。

代码如下:

template <typename T>
class Container{
public:
    static std::vector<T> elements;
    static T* PushOne(){
        //Push a new T object into the vector
        elements.push_back( T{} );
        //Print out its address
        std::cout << "Make " << typeid(T).name() << " at " << &elements[elements.size() - 1] << "n";
        //Return its address.
        return &elements[elements.size() - 1];
    }
};
template <typename T> 
std::vector<T> Container<T>::elements;
class A : public Container<A>{
};
class B : public Container<B>{
};
int main(int argc, char** args){
    std::cout << "First addresses:n";
    //a and c are assigned the address
    auto a = Container<A>::PushOne();
    auto b = Container<A>::PushOne(); //Problem gone if this is commented
    auto c = Container<B>::PushOne();
    std::cout << "nLater addresses:n";
    std::cout   << &Container<A>::elements[0] << "n" 
                << &Container<A>::elements[1] << "n" 
                << &Container<B>::elements[0] << "n";
    std::cin.get();
}

在我的机器上运行一次的输出:

First addresses:
Make class A at 00700350
Make class A at 006FA929
Make class B at 00700350
Later addresses:
006FA928
006FA929
00700350

如您所见,第一个和最后一个条目(分别存储在变量 ab 中)首先打印相同的地址。

当我第二次打印地址时,我得到的第一个 A* 的不同结果。

除非我注释掉auto b = ...行,否则我总是得到相同的结果。如果我这样做,ab会被分配不同的地址。

第二个 push_back/PushOne 会导致std::vector<A>重新分配以增加它,因此现在第一个 A 元素不再位于 00700350

您的Later addresses打印输出证实了这一点。

当你将元素推到向量上时,最终它将需要分配新的内存,并释放旧的内存(其他分配可能会使用)。 所以,显然,当你第二次推迟Container<A>时,发生了重新分配。 然后,当你推送Container<B>时,它的向量使用了另一个向量(Container<A>)释放的内存。 这完全没问题。