在哪些情况下,如果复制了容器,则调用复制构造函数

In which cases is the copy constructor called, if a container is copied

本文关键字:复制 调用 构造函数 情况下 如果      更新时间:2023-10-16

我测试了以下代码:

#include <iostream>
#include <vector>
class foo {
public:
    int m_data;
    foo(int data) : m_data(data) {
        std::cout << "parameterised constructor" << std::endl;
    }
    foo(const foo &other) : m_data(other.m_data) {
        std::cout << "copy constructor" << std::endl;
    }
};
main (int argc, char *argv[]) {
    std::vector<foo> a(3, foo(3));
    std::vector<foo> b(4, foo(4));
    //std::vector<foo> b(3, foo(4));
    std::cout << "a = b" << std::endl;
    a = b;
    return 0;
}

我得到

   parameterised constructor
   copy constructor
   copy constructor
   copy constructor
   parameterised constructor
   copy constructor
   copy constructor
   copy constructor
   copy constructor
   a = b
   copy constructor
   copy constructor
   copy constructor
   copy constructor

但是,如果我将std::vector<foo> b(4, foo(4));替换为std::vector<foo> b(3, foo(4));a = b不会调用复制构造函数,并且输出为

parameterised constructor
copy constructor
copy constructor
copy constructor
parameterised constructor
copy constructor
copy constructor
copy constructor
a = b

为什么在这种情况下不调用复制构造函数?

我正在使用 g++ (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1

在第一种情况下,a在分配给它时需要增长,这意味着它的所有元素都必须重新分配(因此被破坏和构造)。

在第二种情况下,a不需要增长,因此使用赋值运算符。

请参阅 http://ideone.com/atPt9; 添加打印消息的重载复制赋值运算符,我们在第二个示例中得到以下内容:

parameterised constructor
copy constructor
copy constructor
copy constructor
parameterised constructor
copy constructor
copy constructor
copy constructor
a = b
copy assignment
copy assignment
copy assignment

它使用赋值运算符。

#include <iostream>
#include <vector>
class foo {
public:
    int m_data;
    foo(int data) : m_data(data) {
        std::cout << "parameterised constructor " << m_data << std::endl;
    }
    foo(const foo &other) : m_data(other.m_data) {
        std::cout << "copy constructor " << m_data << " " << other.m_data << std::endl;
    }
    foo& operator= (const foo& other){
        std::cout << "assignment operator " << m_data << " " << other.m_data << std::endl;
    }
};
main (int argc, char *argv[]) {
    std::vector<foo> a(3, foo(3));
    //std::vector<foo> b(4, foo(4));
    std::vector<foo> b(3, foo(4));
    std::cout << "a = b" << std::endl;
    a = b;
    for(std::vector<foo>::const_iterator it = a.begin(); it != a.end(); ++it){
        std::cout << "a " << it->m_data << std::endl;
    }
    for(std::vector<foo>::const_iterator it = b.begin(); it != b.end(); ++it){
        std::cout << "b " << it->m_data << std::endl;
    }
    return 0;
}
parameterised constructor 3
copy constructor 3 3
copy constructor 3 3
copy constructor 3 3
parameterised constructor 4
copy constructor 4 4
copy constructor 4 4
copy constructor 4 4
a = b
assignment operator 3 4
assignment operator 3 4
assignment operator 3 4
a 3
a 3
a 3
b 4
b 4
b 4

请参阅奥利斯的答案以了解原因。