Главная->Інформатика та програмування->Содержание->Конструкторы производного класса

ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++ (4-Е ИЗДАНИЕ) (часть 9) онлайн

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

Это потенциальная проблема в программе COUNTEN. Что будет, если мы захотим инициализировать значением объект класса CountDn? Сможем ли мы воспользо- ваться конструктором класса Counter с одним аргументом? Ответ будет отрица- тельным. Как мы видели в программе COUNTEN, компилятор будет использовать

конструктор базового класса без аргументов. Мы должны написать новый конст- руктор для производного класса. Это показано в программе COUNTEN2:

// counten2.cpp

// конструкторы в производных классах

#include <iostream>

using namespace std;

///////////////////////////////////////////////////////////

class Counter

{

  protected:     // заметьте, что тут не следует использовать private

    unsigned int count;              // счетчик

  public:

    Counter ( ) : count ( )          // конструктор без параметров

      { }

    Counter ( int c ) : count ( c )  // конструктор с одним параметром

      { }

    unsigned int get_count ( ) const // получение значения

      { return count; }

    Counter operator++ ( )           // оператор увеличения

      { return Counter ( ++count ); }

};

///////////////////////////////////////////////////////////

class CountDn : public Counter

{

  public:

    CountDn ( ) : Counter ( )        // конструктор без параметров

      { }

    CountDn ( int c ) : Counter ( c )// конструктор с одним параметром

      { }

    CountDn operator-- ( )           // оператор уменьшения

      { return CountDn ( --count ); }

};

///////////////////////////////////////////////////////////

int main ( )

{

  CountDn c1;                            // переменные класса CountDn

  CountDn c2 ( 100 );

 

  cout << "\nc1 = " << c1.get_count ( ); // выводим значения на экран

  cout << "\nc2 = " << c2.get_count ( );

 

  ++c1; ++c1; ++c1;                      // увеличиваем c1

  cout << "\nc1 = " << c1.get_count ( ); // показываем результат

 

  --c2; --c2;                            // уменьшаем c2

  cout << "c2 = " << c2.get_count ( );   // показываем результат

 

  CountDn c3 = --c2;            // создаем переменную c3 на основе c2

  cout << "\nc3 = " << c3.get_count ( ); // показываем значение

 

  cout << endl;

 

  return 0;

}

 

Программа использует два новых конструктора класса CountDn. Это конст- руктор без аргументов:

CountDn ( ) : Counter ( ) { }

В этом конструкторе использована новая для нас возможность: имя функ- ции, следующее за двоеточием. Она используется конструктором класса CountDn для вызова конструктора Counter() базового класса. Когда мы запишем в функ- ции main()

CountDn c1;

компилятор создаст объект класса CountDn и вызовет конструктор класса CountDn для его инициализации. Конструктор в свою очередь вызовет конструктор клас- са Counter, который выполнит нужные действия. Конструктор CountDn() может выполнять и свои операции, кроме вызова другого конструктора, но в нашем случае это не требуется, поэтому пространство между скобками пусто.

Вызов конструктора в списке инициализации может быть лишним, но это имеет смысл. Мы хотим инициализировать поле, не важно, принадлежит оно базовому или производному классу, и перед выполнением любого оператора программы сначала будут выполнены операции конструктора.

В строке:

CountDn c2 ( 100 );

функции main() используется конструктор класса CountDn с одним аргументом. Этот конструктор вызывает соответствующий конструктор с одним аргументом из базового класса:

CountDn ( int c ) : Counter ( с ) // параметр с передается в конструктор класса Counter { }

Такая конструкция означает, что аргумент с будет передан от конструктора CountDn() в Counter(), где будет использован для инициализации объекта.

В функции main() после инициализации объектов c1 и c2 мы увеличиваем один из них и уменьшаем другой, а затем выводим результат. Конструктор с од- ним аргументом также используется в выражениях присваивания:

CountDn c3 = --c2;

 

12