在对valgrind进行了大量研究之后,我得出结论,std::vector会生成一个你想要推回的对象的副本。

这是真的吗?vector不能在没有副本的情况下保留对象的引用或指针?!

谢谢


当前回答

为什么要进行大量的调查才发现这一点! 用一些简单的代码证明一下就可以了。

std::vector<std::string> vec;

{
      std::string obj("hello world");
      vec.push_pack(obj);
}

std::cout << vec[0] << std::endl;  

如果打印"hello world",则该对象必须已被复制

其他回答

为什么要进行大量的调查才发现这一点! 用一些简单的代码证明一下就可以了。

std::vector<std::string> vec;

{
      std::string obj("hello world");
      vec.push_pack(obj);
}

std::cout << vec[0] << std::endl;  

如果打印"hello world",则该对象必须已被复制

是的,std::vector存储副本。vector如何知道对象的预期生命周期是什么?

如果你想要转移或共享对象的所有权,可以使用指针,可能是像shared_ptr这样的智能指针(在Boost或TR1中找到)来简化资源管理。

与c++ 11相关的是emplace家族成员函数,它允许您通过将对象移动到容器中来转移对象的所有权。

习惯用法是这样的

std::vector<Object> objs;

Object l_value_obj { /* initialize */ };
// use object here...

objs.emplace_back(std::move(l_value_obj));

左值对象的move很重要,否则它将被转发为引用或const引用,并且不会调用move构造函数。

从c++ 11开始,所有的标准容器(std::vector, std::map等)都支持move语义,这意味着你现在可以将右值传递给标准容器,避免复制:

// Example object class.
class object
{
private:
    int             m_val1;
    std::string     m_val2;

public:
    // Constructor for object class.
    object(int val1, std::string &&val2) :
        m_val1(val1),
        m_val2(std::move(val2))
    {

    }
};

std::vector<object> myList;

// #1 Copy into the vector.
object foo1(1, "foo");
myList.push_back(foo1);

// #2 Move into the vector (no copy).
object foo2(1024, "bar");
myList.push_back(std::move(foo2));

// #3 Move temporary into vector (no copy).
myList.push_back(object(453, "baz"));

// #4 Create instance of object directly inside the vector (no copy, no move).
myList.emplace_back(453, "qux");

或者,你也可以使用各种智能指针来获得大致相同的效果:

std:: unique_ptr例子

std::vector<std::unique_ptr<object>> myPtrList;

// #5a unique_ptr can only ever be moved.
auto pFoo = std::make_unique<object>(1, "foo");
myPtrList.push_back(std::move(pFoo));

// #5b unique_ptr can only ever be moved.
myPtrList.push_back(std::make_unique<object>(1, "foo"));

std::要查看示例

std::vector<std::shared_ptr<object>> objectPtrList2;

// #6 shared_ptr can be used to retain a copy of the pointer and update both the vector
// value and the local copy simultaneously.
auto pFooShared = std::make_shared<object>(1, "foo");
objectPtrList2.push_back(pFooShared);
// Pointer to object stored in the vector, but pFooShared is still valid.

是的,std::vector<T>::push_back()创建参数的副本并将其存储在vector中。如果你想在向量中存储指向对象的指针,创建std::vector<whatever*>而不是std::vector<whatever>。

但是,您需要确保指针引用的对象在vector保存对它们的引用时仍然有效(利用RAII习惯用法的智能指针解决了这个问题)。