我使用Visual Studio旗舰2013预览,Windows 7的两个对象似乎共享相同的地址
我使用CRTP能够方便地将任何类型的对象到一个单独的载体。
但是结果很奇怪。你会看到我有两个类,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();
}
输出从一个跑在我的机器上:
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元素不再位于00700350?之后我会检查所有地址。 编辑:您稍后的地址证实了这一点 – Matthias247
@ Matthias247猜猜你是对的,如果我在使用前“保留”,问题就会消失,以防止重新分配。如果您希望我接受它,请给出答案。先到先得 ;) – s3rius