使用STL向量复制构造函数与赋值运算符

Copy constructor vs assignment operator with STL vector

有这个class:

class A
{
    int number;
    int number2;
public:
    A(int _number):number(_number),number2(0)
    {
        cout<<"Normal constructor\n";
    }
    A()
    {
        cout<<"Default constructor\n";
    }

    A(const A& source)
    {
        number = source.number;
        number2 = source.number2;
        cout<<"Copy constructor\n";
    }

    A & operator=(const A& source)
    {
        number = source.number;
        number2 = source.number2;
        cout<<"Assignment operator\n";
        return *this;
    }
};

如果创建了 vector<A> obj {1,2,3}normal constructor 被调用了三次,因为它没有声明为 explicit,因此它被用作 converting constructor。然后 copy constructor 被调用了三次。

如果执行 vector<A> obj_1;,将创建一个可以容纳类型 A 对象的空向量 - 没有调用构造函数但对象存在.


来自 this link:

  1. 复制构造函数用于根据其他对象的数据初始化先前未初始化的对象。

  2. 赋值运算符用于用其他对象的数据替换先前初始化对象的数据。


执行 obj_1 = obj,如果我的 obj_1 之前已初始化,则会导致在我的 class [=19= 中调用 copy constructor 而不是 operator= 函数] 如我所料?

此外,在 vector 中已经有一个 operator= 函数。我怎么知道什么时候调用每个?

vector<A> obj {1,2,3};
vector<A> obj_1;
obj_1 = obj;  // Why copy constructor called instead of function operator= inside my class

Is there any way a vector can be declared and instantiated while skipping the copying operation?

没有。当您执行 vector<A> obj {1,2,3} 时,编译器会根据提供的值创建一个 std::initializer_list<A>std::initializer_list 创建是您看到三个正常构造函数调用的原因。然后 vector 必须复制这些元素,因为这些元素的底层存储是 const。没有办法通过列表初始化来解决这个问题。即使 vector<A> obj {A(1),A(2),A(3)} 仍然会导致复制。

如果您不想那样做,您可以做的一件事是使用 reserve 为元素创建存储空间,然后使用 emplace_back 直接构造向量中的对象,例如

vector<A> obj;
obj.reserve(3);
for (int i = 1; i < 4, ++i)
    obj.emplace_back(i);

Doing obj_1 = obj, if my obj_1 was previously initialized results in calling the copy constructor instead of operator= function inside my class A as I was expecting?

这是因为 obj_1 是空的。因为它是空的,所以没有元素可以调用赋值运算符。相反,它所做的是在 obj_1 中创建元素,这些元素是 obj 的副本,最有效的方法是只调用复制构造函数而不是默认构造对象然后分配给它们。

如果你有

vector<A> obj {1,2,3};
vector<A> obj_1 {3, 4, 5};
obj_1 = obj; 

相反,您会看到使用赋值运算符代替,因为实际上有对象要分配给。