Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 两个对象似乎共享同一地址_C++_Visual Studio_Templates - Fatal编程技术网

C++ 两个对象似乎共享同一地址

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

我正在使用Visual Studio Ultimate 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();
}
如您所见,第一个和最后一个条目(分别存储在变量
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