C++ 两个对象似乎共享同一地址
我正在使用Visual Studio Ultimate 2013预览版,Windows 7 我使用CRTP能够方便地将任何类型的对象推送到一个单独的向量中 然而,结果却很奇怪。您将看到我有两个类,C++ 两个对象似乎共享同一地址,c++,visual-studio,templates,C++,Visual Studio,Templates,我正在使用Visual Studio Ultimate 2013预览版,Windows 7 我使用CRTP能够方便地将任何类型的对象推送到一个单独的向量中 然而,结果却很奇怪。您将看到我有两个类,A和B,它们派生自Container。使用T*PushOne()将一个新实例推送到一个静态向量中,并返回其地址以供使用 由于某种原因,类A的第一个实例化对象和类B的第一个实例化对象似乎共享相同的地址 代码如下: template <typename T> class Container{ p
A
和B
,它们派生自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();
}
如您所见,第一个和最后一个条目(分别存储在变量a
和b
中)首先打印相同的地址
当我第二次打印地址时,我得到的第一个a*的结果不同
我总是得到相同的结果,除非我注释掉行
auto b=…
。如果我这样做,a
和b
被分配不同的地址。当你把元素推到向量上时,它最终需要分配新内存,并释放旧内存(其他分配可能会使用)。因此,显然,当您第二次向后推容器时,发生了重新分配。然后,当您按下容器
时,它的向量使用了另一个向量(属于容器
)释放的内存。这是完全正确的。第二次推回/推回导致重新分配std::vector以使其增长,这样现在第一个a元素不再位于00700350
您的后期地址
打印输出证实了这一点。也许第二个推回/推回
会导致在std::vector上重新分配以使其增长,因此现在第一个a元素不再位于00700350?之后我会检查所有的地址。编辑:您以后的地址确认this@Matthias247我猜你是对的,如果我在使用前保留,问题就会消失,以防止重新分配。如果你想让我接受,就回答吧。先到先得;)
First addresses:
Make class A at 00700350
Make class A at 006FA929
Make class B at 00700350
Later addresses:
006FA928
006FA929
00700350