Конструкторы в языке C++


1.     Понятие и объявление конструктора класса
2.     Виды конструкторов. Особенности и правила работы с конструкторами.


1.     Понятие и объявление конструктора класса
Конструктор – это метод класса, имя которого совпадает с именем класса. Конструктор вызывается автоматически после выделения памяти для переменной и обеспечивает инициализацию компонент – данных. Конструктор не имеет никакого типа (даже типа void) и не возвращает никакого значения в результате своей работы. Конструктор нельзя вызывать как обычную компонентную функцию в программе. Для класса может быть объявлено несколько конструкторов, различающихся числом и типами параметров. При этом даже если для объектного типа не определено ни одного конструктора, компилятор создает для него конструктор по умолчанию, не использующий параметров, а также конструктор копирования, необходимый в том случае, если переменная объектного типа передается в конструктор как аргумент. В этом случае создаваемый объект будет точной копией аргумента конструктора.


class my_Fun
{
// компоненты-данные
double x;
unsigned size;
public:
// объявление конструктора 1 (с параметрами)
my_Fun (double X=0);

// объявление конструктора 2 (без параметров)
my_Fun(void);
// объявление и описание деструктора
~my_Fun ()
{
cout<<"Destroyed object... "<<endl;
}
// описание конструктора 1
my_Fun::my_Fun (double X)
{
cout<<"Constructor1...."<<endl;
x=X;
}
// описание конструктора 2
my_Fun::my_Fun (void)
{
cout<<"Constructor2..."<<endl;
x=5.0;
}
}

2.     Виды конструкторов. Особенности и правила работы с конструкторами.
Недостатком рассмотренных ранее классов является отсутствие автоматической инициализации создаваемых объектов. Для каждого вновь создаваемого объекта необходимо было вызвать функцию типа set (как для класса complex) либо явным образом присваивать значения данным объекта. Однако для инициализации объектов класса в его определение можно явно включить специальную компонентную функцию, называемую конструктором.
   Конструкторы и деструкторы в С++ вызываются автоматически, что гарантирует правильное создание и разрушение объектов класса.

   Общий вид (синтаксис) объявления конструктора:

class className
{
public:
   className();                     // конструктор по умолчанию
   className(const className &c);   // конструктор копии
   className(<список параметров>);  // конструктор с параметрами
};

   Пример 2:

// Замечание: Здесь только объявление класса без описания объявленных
// функций-параметров

class point
{
protected:
   double x;
   double y;
public:
   point();
   point(double xVal, double yVal);
   point(const point &pt);
   double getX();
   double getY();
   void assign(double xVal, double yVal);
   point& assign(point &pt);
};
int main()
{
  point p1;
  point p2(10, 20);
  point p3(p2);
  p1.assign(p2);
  cout << p1.getX() << " " << p1.getY() << endl;
  cout << p2.getX() << " " << p2.getY() << endl;
  cout << p3.getX() << " " << p3.getY() << endl;
  return 0;
}

   Конструктор копии создает объект класса, копируя при этом данные из существующего объекта класса.

   В С++ имеются следующие особенности и правила работы с конструкторами:

1.     Имя конструктора класса должно совпадать с именем класса.
2.     Нельзя определять тип возвращаемого значения для конструктора, даже тип void.
3.     Класс может иметь несколько конструкторов или не иметь их совсем.
4.     Конструктором по умолчанию является конструктор, не имеющий параметров, или конструктор, у которого все параметры имеют значения по умолчанию.

   Рассмотрим два примера с фрагментами объявления конструкторов.

// класс с конструктором без параметров
class point1
{
protected:
   double x;
   double y;
public:
   point1();
   // другие функции-элементы
};

// конструктор класса имеет параметры со значениями по умолчанию
class point2
{
protected:
   double x;
   double y;
public:
   point2(double xVal = 0, double yVal = 0);
   // другие функции-элементы
};

5.     Конструктор копии создает объект класса на основе существующего объекта.

Например:

class point
{
protected:
   double x;
   double y;
public:
   point();
   point(double xVal = 0, double yVal = 0);
   point(const point &pt);
   // другие функции-элементы
};

6.     Объявление объекта класса, которое может содержать параметры и, в качестве параметра, имя уже существующего объекта, влечет за собой вызов конструктора. Но какой из конструкторов будет использоваться в каждом конкретном случае? Ответ зависит от того, как много конструкторов вы объявили и с какими аргументами вы объявляете объект класса. Например, рассмотрим следующие объявления объектов последней версии класса point:

point p1;                  // применяется конструктор по умолчанию
point p2(1.1, 1.3);   // используется второй по счету конструктор
point p3(p2);           // используется конструктор копии

   Поскольку объект p1 объявляется без параметров, компилятор использует
конструктор по умолчанию. Объект p2 объявляется с двумя вещественными
аргументами, поэтому компилятор вызовет второй конструктор. Объект p3
при объявлении имеет параметром объект p2, поэтому компилятор вызовет
конструктор копии, чтобы создать новый объект из объекта p2.

   ВНИМАНИЕ:

   Определяйте конструктор копии, особенно для классов, моделирующих динамические структуры данных. Конструкторы копии должны выполнять т.н. глубокое копирование, которое подразумевает копирование динамических данных. Если вы не определили конструктор копии, компилятор создаст конструктор копии по умолчанию, который будет создавать поверхностную копию, копируя только элементы-данные. При этом будет скопировано содержимое данных-элементов, содержащих указатели на другие, данные, но сами эти данные скопированы не будут.
   Не полагайтесь на поверхностный конструктор копии для классов имеющих данные-указатели.