我正在使用 Windows 7 的 Visual Studio Ultimate 2013 预览版。
我使用 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
分配不同的地址。