我使用的是 Visual Studio Ultimate 2013 Preview,Windows 7。
我使用 CRTP 能够方便地将任何类型的对象推送到单独的 vector 中。
然而,结果很奇怪。您会看到我有两个类,A
和 B
,它们派生自 Container
。使用 T* PushOne()
,一个新实例被插入一个静态 vector ,它的地址被返回以供使用。
由于某些原因,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
如您所见,第一个和最后一个条目(分别存储在变量 a
和 b
中)首先打印相同的地址。
当我第二次打印地址时,第一次 A* 得到了不同的结果。
我总是得到相同的结果,除非我注释掉 auto b = ...
行。如果我这样做,a
和 b
会被分配不同的地址。
最佳答案
第二个 push_back/PushOne 导致在您的 std::vector<A>
上重新分配增长它,这样现在第一个 A 元素不再位于 00700350
.
你的 Later addresses
打印输出证实了这一点。
关于c++ - 两个对象似乎共享同一个地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19322702/