Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Конструкторы и наследование




 

В иерархии классов конструктор базового класса конструирует часть объекта, относящуюся к базовому классу, а конструктор производного класса конструирует часть, относящуюся к производному классу.

 

Примеры

1. Если конструктор определен только в производном классе, процесс построения объекта очевиден: надо просто сконструировать объект производного класса. Часть объекта, относящаяся к базовому классу, конструируется автоматически конструктором базового класса по умолчанию.

Ниже приведен переработанный вариант класса Triangle, в котором определен конструктор. Кроме того, член style объявлен закрытым, поскольку теперь его будет устанавливать конструктор:

 

// Добавление конструктора в производный класс Triangle.

 

#include "stdafx.h"

#include <iostream>

#include <cstring>

#include <conio.h>

using namespace std;

 

// Класс для двумерных объектов.

class TwoDShape {

// эти члены закрыты

double width;

double height;

public:

void showDim() {

cout << "width and height are "

<< width << " and " << height << "\n"; }

//функции доступа

double getWidth() { return width; }

double getHeight () { return height; }

void setWidth(double w) { width = w; }

void setHeight (double h) { height = h; }

};

 

// Triangle является производным от TwoDShape.

class Triangle: public TwoDShape {

char style[20];

public:

//Конструктор для класса Triangle.

Triangle(char *str, double w, double h) {

// Инициализация части, относящейся к базовому классу.

setWidth (w);

setHeight (h);

// Инициализация части, относящейся к производному классу.

strcpy_s (style, str);

}

double area() {

return getWidth() * getHeight() /2;

}

void showStyle() {

cout << "Triangle " << style << "\n"; }

};

 

int main () {

Triangle t1("isosceles", 4.0, 4.0);

Triangle t2("rectangular", 8.0, 12.0);

 

cout << "Data of object tl:\n";

t1.showStyle();

t1.showDim();

 

cout << "Arae equal " << t1.area() << "\n";

cout << "\n";

 

cout << "Data of object t2:\n";

t2.showStyle();

t2.showDim();

cout << "Area equal " << t2.area() << "\n";

_getch();

return 0;

}

 

В этой программе конструктор класса Triangle инициализирует члены TwoDShape, которые Triangle наследует от TwoDShape, а также, собственное поле style.

 

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

Если в базовом классе есть свой конструктор, производный классдолжен вызывать его явным образом, чтобы инициализировать часть объекта, относящуюся к базовому классу. Производный класс может вызывать конструктор, определенный в базовом классе, посредством расширенной формы объявления конструктора производного класса. Общая форма этого расширенного объявления выглядит так:

производный-конструктор (список-всех-аргументов): базовый-конструктор (список-аргументо-базового класса)

{

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

}

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

Приведенная ниже программа показывает способ передачи аргументов конструктору базового класса. В ней определен конструктор класса TwoDShape, который инициализирует переменные width и height:

 

// Добавление конструктора в базовый класс TwoDShape.

 

#include "stdafx.h"

#include <iostream>

#include <cstring>

#include <conio.h>

using namespace std;

 

// Класс для двумерных объектов.

class TwoDShape {

// эти члены закрыты

double width;

double height;

public:

// Конструктор для TwoDShape.

TwoDShape(double w, double h) {

width = w;

height = h;

}

void showDim () {

cout << "width and height are " << width

<< " и " << height << "\n";

}

// функции доступа

double getWidth() { return width; }

double getHeight () { return height; }

void setWidth (double w) { width = w; }

void setHeight (double h) { height = h; }

};

 

// Triangle является производным от TwoDShape.

class Triangle: public TwoDShape {

char style[20]; // теперь private

public:

// Конструктор для класса Triangle.

Triangle(char *str, double w, double h): TwoDShape (w, h) {

strcpy_s(style, str);

}

double area () {

return getWidth() * getHeight () / 2;

}

void showStyle() {

cout << "Triangle " << style << "\n";

}

};

 

int main() {

Triangle t1("isosceles", 4.0, 4.0);

Triangle t2("rectangular", 8.0, 12.0);

 

cout << "Data of object tl:\n";

t1.showStyle();

t1.showDim();

cout << "Area equal " << t1.area() << "\n";

cout << "\n";

 

cout << "Data of object t2:\n";

t2.showStyle();

t2.showDim();

cout << "Area equal " << t2.area() << "\n";

 

_getch();

return 0;

}

 

В этой программе Triangle() вызывает TwoDShape с параметрами w и h, которые инициализируют переменные width и height этими значениями. Triangle уже не инициализирует их сам. Ему требуется инициализировать только переменную, специфическую для этого класса, именно, style. Такая процедура оставляет за TwoDShape возможность конструировать свои подобъекты любым способом, какой ему будет удобен. Более того, TwoDShape может увеличить свои функциональные возможности, о чем существующие производные классы ничего не будут знать, и это не приведет к разрушению существующих программ.

 

3. Конструктором производного класса может быть вызвана любая форма конструкторов из определенных в базовом классе. Выполняться будет конструктор с соответствующим списком аргументов. Ниже приведены расширенные варианты обоих классов, TWoDShape и Triangle, которые включают дополнительные конструкторы:

 

/* Добавление в базовый класс TwoDShape и в производный класс Triangle

перегруженных (нескольких) конструкторов.*/

#include "stdafx.h"

#include <iostream>

#include <cstring>

#include <conio.h>

using namespace std;

 

//Класс для двумерных объектов.

class TwoDShape {

double width;

double height;

public:

// Конструктор по умолчанию.

TwoDShape () {

width = height = 0.0;

}

// Конструктор с параметрами для TwoDShape.

TwoDShape(double w, double h) {

width = w; height = h;

}

// Конструируем объект с равными шириной и высотой.

TwoDShape(double x) {

width = height = x;

}

void showDim () {

cout << "Width and height are "

<< width << " and " << height << "\n";

}

// функции доступа

double getWidth() { return width; }

double getHeight () { return height; }

void setWidth (double w) { width = w; }

void setHeight (double h) { height = h; }

};

 

// Triangle является производным от TwoDShape.

class Triangle: public TwoDShape {

char style [20];

public:

/* Конструктор по умолчанию. Он автоматически вызывает

конструктор по умолчанию TwoDShape. */

Triangle() {

strcpy_s(style, "unknown");

}

// Конструктор с тремя параметрами.

Triangle(char *str, double w, double h): TwoDShape (w, h){

strcpy_s (style, str);

}

// Сконструируем равнобедренный треугольник.

Triangle(double x): TwoDShape(x) {

strcpy_s(style, "isosceles");

}

 

double area() {

return getWidth() * getHeight() / 2;

}

void showStyle() {

cout << "Triangle " << style << "\n";

}

};

 

int main () {

Triangle t1;

Triangle t2("rectangular", 8.0, 12.0);

Triangle t3 (4.0);

 

cout << "Data of оbject tl: \n";

t1.showStyle ();

t1.showDim();

cout << "Area equal " << t1.area() << "\n\n";

 

cout << "Data of object t2: \n";

t2.showStyle();

t2.showDim();

cout << "Area equal " << t2.area() << "\n\n";

 

cout << "Data оf object t3: \n";

t3.showStyle();

t3.showDim();

cout << "Area equal " << t3.area() << "\n\n";

_getch();

return 0;

}

Вот вывод этой программы:

 

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...