NiklausTseng
NiklausTseng

Reputation: 235

About copy control in C++

I defined a class named Student.

// Student.h
#pragma once
#include <iostream>
using namespace std;

class Student {
public:
    Student();
    Student(const Student &s);
    Student(int ii);
    Student& operator=(const Student &s);
    ~Student();
private:
    int i;
};

// Student.cpp
#include "Student.h"

Student::Student(): i(0)
{
    cout << "ctor" << endl;
}

Student::Student(const Student &s)
{
    i = s.i;
    cout << "copy constructor" << endl;
}

Student::Student(int ii): i(ii)
{
    cout << "Student(int ii)" <<  endl;
}

Student& Student::operator=(const Student &s)
{
    cout << "assignment operator" << endl;
    i = s.i;
    return *this;
}

Student::~Student()
{
}

// main.cpp
#include <vector>
#include "Student.h"

int main()
{
    vector<Student> s(5);
    system("pause");
    return 0;
}

I ran this program on Visual Studio 2015.
Output result:

ctor  
ctor  
ctor  
ctor  
ctor  

But I expect the result is:

ctor  
copy constructor  
copy constructor  
copy constructor  
copy constructor  
copy constructor  

Am I wrong? Additionally, I wrote:

Student s1;
Student s2 = s1;

Output result:

ctor  
copy constructor  

instead of:

ctor  
copy constructor  
copy constructor  

as C++ primer(the fourth edition) said in Chapter 13.

The third one, when I wrote:

Student s = 3;

Output result:

Student(int ii)

I think this one should be:

Student(int ii)  
copy constructor  

Upvotes: 2

Views: 1542

Answers (1)

NathanOliver
NathanOliver

Reputation: 180955

If you consult the documentation on std::vector::vector(size_type count) You would see that

Constructs the container with count default-inserted instances of T. No copies are made.

So you only will see constructor calls.

Secondly in

Student s1;
Student s2 = s1;

s2 = s1 is not using the assignment operator but instead it is using copy initialization. This uses the copy constructor to construct the string.

In your third example

Student(int ii)  
copy constructor  

Would be a valid output. The reason you do not get that is that the compiler is smart and instead of creating a temporary Student and then making a copy it can elide out the copy and directly construct s using the constructor that takes an int.

Upvotes: 7

Related Questions