STL容器如何复制对象?

发布于 2024-08-10 13:34:00 字数 630 浏览 3 评论 0原文

我知道像 vector 这样的 STL 容器在添加对象时会复制该对象。 push_back 方法如下所示:

void push_back ( const T& x );

我很惊讶地发现它将该项目作为参考。我编写了一个示例程序来看看它是如何工作的。

struct Foo
{
    Foo()
    {
        std::cout << "Inside Foo constructor" << std::endl;
    }

    Foo(const Foo& f)
    {
        std::cout << "inside copy constructor" << std::endl;
    }
};

Foo f;
std::vector<Foo> foos;
foos.push_back(f);

这会复制对象,我可以看到它正在调用复制构造函数。

我的问题是,当push_back以item为参考时,它如何调用复制构造函数?或者我在这里遗漏了什么?

有什么想法吗..?

I know STL containers like vector copies the object when it is added. push_back method looks like:

void push_back ( const T& x );

I am surprised to see that it takes the item as reference. I wrote a sample program to see how it works.

struct Foo
{
    Foo()
    {
        std::cout << "Inside Foo constructor" << std::endl;
    }

    Foo(const Foo& f)
    {
        std::cout << "inside copy constructor" << std::endl;
    }
};

Foo f;
std::vector<Foo> foos;
foos.push_back(f);

This copies the object and I can see it is calling copy-constructor.

My question is, when the push_back takes item as reference, how it is calling copy-constructor? Or am I missing something here?

Any thoughts..?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

迷爱 2024-08-17 13:34:00

它可能使用“placement new”在其内部数组中就地构造对象。放置new不分配任何内存;它只是将对象放置在您指定的位置,然后调用构造函数。语法为new (address) Class(constructor_arguments)

调用复制构造函数 T::T(T const &) 来就地创建副本。像这样(简化):

template<T>
void vector<T>::push_back(T const &item) {
    // resize if necessary
    new (&d_array[d_size++]) T(item);
}

请注意,T 必须有一个复制构造函数才能工作。默认情况下(如果您什么都不做),它会免费获得一个。如果您显式定义它,则它必须是 public 才能使 vector 正常工作。

这是 GNU 的 libstdc++ 的做法,但我对此表示怀疑这将很有启发。有一个分配器(vector 的第二个模板参数)使其变得不那么简单。

It probably uses "placement new" to construct the object in-place in its internal array. Placement new doesn't allocate any memory; it just places the object where you specify, and calls the constructor. The syntax is new (address) Class(constructor_arguments).

The copy constructor T::T(T const &) is called to create the copy in-place. Something like this (simplified):

template<T>
void vector<T>::push_back(T const &item) {
    // resize if necessary
    new (&d_array[d_size++]) T(item);
}

Note that T must have a copy constructor for this to work. By default (if you do nothing), it gets one for free. If you define it explicitly, it must be public for vector<T> to work.

Here's how GNU's libstdc++ does it, but I doubt that it'll be very enlightening. There is an allocator (the second template argument to vector) that makes it less straightforward.

一影成城 2024-08-17 13:34:00

为了提高效率,C++ SDK 始终采用 const T & 作为函数参数。

在您的情况下,如果它以 T 作为参数,则复制操作将执行两次,一次将其传递给函数 push_back(f),一次用于内部将其添加到容器。通过使用 const T& 作为参数,只需要一份副本!

The C++ SDK always takes const T & as function parameter for efficiency.

In your case if it take T as parameter, the copy action will be done twice, one for passing it to function push_back(f), one for internal adding it to the container. And by taking const T& as parameter only one copy is needed!

笑,眼淚并存 2024-08-17 13:34:00

它使用放置新运算符并将其复制构造到统一内存;

放置 new 在内存中的指定地址创建一个新元素,在向量情况下,是当前的 end();

void push_back(const T& val){
::new (&*end()) T(val);
[increase end]
}

看看 http://spotep.com/dev/devector.h ,它有非常清晰的代码(与大多数 STL 实现相反)。

It uses the placement new operator and copy-constructs it to unitialized memory;

The placement new creates a new element at a specified adress in memory, in the vector case, the current end();

void push_back(const T& val){
::new (&*end()) T(val);
[increase end]
}

look at http://spotep.com/dev/devector.h which has quite clear code (as opposed to most STL implementations).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文