Вызов конструктора копирования C ++ - PullRequest
0 голосов
/ 18 марта 2011

Быстрый вопрос. Если у меня есть массив и я правильно перегрузил оператор присваивания, то когда я делаю что-то вроде этого:

A = B 

Когда A и B оба являются объектами типа array, я вызываю конструктор копирования или просто перегруженный оператор присваивания (=)?

Я знаю, что конструктор копирования вызывается, когда

  1. Передать по значению
  2. возвращает значение типа класса
  3. когда объект объявляется и инициализируется другим объектом того же типа, указанного в скобках.

3 выше меня смущает и я думаю, что A = B также вызывает конструктор копирования.

Это просто вызов перегруженного оператора присваивания?

Спасибо!

Ответы [ 5 ]

3 голосов
/ 18 марта 2011

Ничего из вышеперечисленного: вы не можете назначать массивы.


Если у вас есть собственный класс массива, и у него есть что-то вроде этого:

struct arr
{
    arr& operator=(const arr& other)
    {
        // ...
    }
};

arr a, b;

Тогда это эквивалентно:

a = b;
a.operator=(b);

Это похоже на вызов функции.

1 голос
/ 18 марта 2011

Поскольку вы сказали, что массив - это ваш собственный класс с перегруженным оператором присваивания, вы уже ответили на свой вопрос.

Конструктор копирования вызывается буквально только тогда, когда вы создаете объект из другого:

Obj a;Obj b (a);

Может случиться так, что вас вызовет какая-то магия компилятора, если вы сделаете:

Obj a;Obj b = a;

Но я никогда не удосужился посмотреть на это.

Если вы просто делаете a = b, вы не создаете a, поэтому вы не будете вызывать конструктор копирования.

Имеет смысл?

0 голосов
/ 18 марта 2011

3, приведенная выше, приводит меня в замешательство и я думаю, что A = B также вызывает конструктор копирования.

Если ваш конструктор копирования не объявлен explicit, следующее действительно вызовет конструктор копирования:

MyType A = B; // will call copy ctor

Я полагаю, что стандарт гарантирует это (у меня нет справочной информации), так что вы знаете, что не будете вызывать ctor по умолчанию, за которым следует оператор присваивания.

0 голосов
/ 18 марта 2011

Конструктор копирования называется, как вы сказали, когда

  1. Передать по значению
  2. возвращает значение типа класса
  3. когда объект объявляется и инициализируется другим объектом того же типа, указанного в скобках или как присваивание.

Рассмотрим вывод следующего кода:

#include <iostream>

using std::cout;

class Test
{
public:
    Test()
    {
    }
    Test(const Test& T)
    {
        cout << "Calling Copy Constructor";
    }
};

void PassingValue(Test T)
{
    cout << " while Passing parameter by value\n\n";
}

void PassingReference(Test &T)
{
    cout << "NOT CALLING copy constructor while Passsing Parameter by reference\n\n";
}

int main()
{
    Test One;
    // case 1 :
    cout << "case 1 : \n";
    Test Two(One);
    cout << " while creating Two as a copy of One\n\n";
    // case 2 :
    cout << "case 2 : \n";
    PassingValue(One);
    // case 3 :
    cout << "case 3 : \n";
    Test Three = Two;
    cout << " while assigning initial value\n\n";
    // case 4 :
    cout << "case 4 : \n";
    PassingReference(Two);
    // case 5
    cout << "case 5 : \n";
    Test Four;
    Four = Three;
    cout << "NOT CALLING copy constructor while assigning normally\n\n";
    return 0;
}
0 голосов
/ 18 марта 2011

Перегруженный оператор присваивания вызывается, если выполняется A=B;

class userDefinedArray
{
    int size ;
    int* ptr;

    public:
    userDefinedArray( int size ) :   size(size)
                                   , ptr( new int[size] )
    {}
    // The Big Three = 1. Copy Constructor 2. Assignment Operator 3. Destructor
};

Если выше приведено определение класса, то должен быть вызван оператор присваивания.

...