Копировать конструктор и конструктор по умолчанию

Нужно ли явно определять конструктор по умолчанию, когда мы определяем конструктор копирования для класса? Просьба привести причины.

например:

class A 
{
    int i;

    public:
           A(A& a)
           {
               i = a.i; //Ok this is corrected....
           }

           A() { } //Is this required if we write the above copy constructor??
};      

Кроме того, если мы определяем любой другой параметризованный конструктор для класса, отличного от конструктора копирования, нам также нужно определить конструктор по умолчанию? Рассмотрим приведенный выше код без конструктора копирования и замените его на

A(int z)
{
    z.i = 10;
}

Alrite.... После просмотра ответов я написал следующую программу.

#include <iostream>

using namespace std;

class X
{
    int i;

    public:
            //X();
            X(int ii);
            void print();
};

//X::X() { }

X::X(int ii)
{
    i = ii;
}


void X::print()
{
    cout<<"i = "<<i<<endl;
}

int main(void)
{
    X x(10);
  //X x1;
    x.print();
  //x1.print();
}

И если эта программа работает нормально без конструктора по умолчанию. Пожалуйста, объясните, почему это так? Я действительно смущен концепцией.....

Ответ 1

Да. Когда вы явно объявляете абсолютно любой конструктор для класса, компилятор перестает предоставлять неявный конструктор по умолчанию. Если вам по-прежнему нужен конструктор по умолчанию, вы должны явно объявить его и определить самостоятельно.

P.S. Можно написать конструктор копирования (или конструктор преобразования или любой другой конструктор), который также является конструктором по умолчанию. Если ваш новый конструктор попадает в эту категорию, больше нет необходимости предоставлять дополнительный конструктор по умолчанию:)

Например:

// Just a sketch of one possible technique    
struct S {
  S(const S&);
  S(int) {}
};

S dummy(0);

S::S(const S& = dummy) {
}

В приведенном выше примере конструктор копирования является в то же время конструктором по умолчанию.

Ответ 2

Вам не обязательно определять и то, и другое. Однако, как только вы определяете какие-либо конструкторы для класса, все значения по умолчанию становятся недоступными. Итак, если вы хотите как copy-construct, так и построить без копирования, вам нужно также определить конструктор по умолчанию (то есть явный) по умолчанию (то есть без параметров).

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

Ответ 3

Как сказал AndreyT, если вы явно объявляете какой-либо конструктор, включая конструктор копирования, компилятор не будет явно объявлять или определять конструктор по умолчанию.

Это не всегда проблема.

Если вы не хотите, чтобы ваш класс был по-умолчанию конструктивным, то это совершенно прекрасно, чтобы не объявлять конструктор по умолчанию. Но если вы хотите, чтобы он был конструктивным по умолчанию (например, если вы хотите раскомментировать строку X x1; в своем примере), вы должны объявить и определить конструктор по умолчанию.

Также обратите внимание, что конструктор по умолчанию - это любой конструктор, который может быть вызван без аргументов, а не только без аргументов. X::X(int = 5) - совершенно прекрасный конструктор по умолчанию.

Ответ 4

1) Конструктор без аргумента называется конструктором по умолчанию. 2) Если пользователь не предоставил ни один из следующих конструкторов, компилятор объявляет  конструктор по умолчанию для вас.

  2a) Copy Constructor
  2b) Non-default constructor
  2C) default constructor. 

3) Если компиляторы объявляют "конструктор по умолчанию", то говорят, что это "неявно объявленный конструктор по умолчанию",

4) "Неявно объявленный конструктор по умолчанию" имеет два типа

   4a) **trivial** Constructor
   4b) **non-trivial** Constructor. 

5) Непосредственно объявленный конструктор по умолчанию называется "тривиальным", когда есть     5a) Нет контрольной переменной     5b) Нет виртуальной функции     5c) Нет виртуального базового класса.     5d) Родительский класс имеет тривиальный конструктор,

Else, it is said to be 'non-trivial'.

Надеюсь, это поможет.