Пример.
Пример на основе 4 классов: Spine, Mammal, Dog и Pug
#include "pch.h"
#include <iostream>
#include <string>
using namespace std;
#define _CRT_SECURE_NO_WARNINGS
/*Создаем класс Spine(Позвоночник)*/
class Spine
{
/*Объявляем переменную lengthSpine(Длина позвоночника) типа float и
переменную WallColor(Название позвоночника) типа string c модификатором доступа private */
private:
float lengthSpine;
string nameSpine;
public:
/*Объявляем конструктор по умолчанию*/
Spine()
{
/*Производим отладочную печать работы конструктора по умолчанию и инициализируем переменные lengthSpine и nameSpine */
cout << "Конструктор по умолчанию Spine" << endl;
lengthSpine = 0.6;
nameSpine = "Грудной";
}
/*Объявляем конструктор, который принимает в качестве параметров две переменные:
lengthSpine типа float и nameSpine типа string.
В инициализации конструктора инициализируем переменные lengthSpine и nameSpine полученными значениями */
Spine(float lengthSpine, string nameSpine) : lengthSpine(lengthSpine), nameSpine(nameSpine)
{
/*Производим отладочную печать работы конструктора с параметром*/
cout << "Конструктор c параметрами Spine" << endl;
}
/*Объявляем конструктор копирования Spine, который принимает в качестве параметра объект Spine с именем cpySpine
В инициалиации конструктора копируем поля объекта cpySpine в lengthSpine и nameSpine соответственно скопированным значениями*/
Spine(const Spine& cpySpine) : lengthSpine(cpySpine.lengthSpine), nameSpine(cpySpine.nameSpine)
{
/*Производим отладочную печать работы конструктора копирования*/
cout << "Конструктор копирования Spine" << endl;
}
/*Объявляем перегруженный оператор присваивания*/
Spine& operator=(const Spine &spine)
{
/*Производим отладочную печать работы перегруженного оператора присваивания
Копируем поля объекта cpySpine в lengthSpine и nameSpine соответственно*/
cout << "Перегруженный оператор присваивания Spine" << endl;
this->lengthSpine = spine.lengthSpine;
this->nameSpine = spine.nameSpine;
/*Возвращаем текущий объект*/
return *this;
}
/*Объявляем деструктор*/
~Spine()
{
/*Производим отладочную печать работы деструктора*/
cout << "Деструктор Spine" << endl;
}
/*Объявляем setter для записи значения в private lengthSpine*/
void setLengthSpine(float lengthSpine)
{
this->lengthSpine = lengthSpine;
}
/*Объявляем getter для получения значения из private lengthSpine*/
float getLengthSpine()
{
return lengthSpine;
}
/*Объявляем setter для записи значения в private nameSpine*/
void setNameSpine(string nameSpine)
{
this->nameSpine = nameSpine;
}
/*Объявляем getter для получения значения из private nameSpine*/
string getNameSpine()
{
return nameSpine;
}
/*Метод вывода print полей класса*/
void print()
{
cout << "Длина позвоночника: " << lengthSpine << " м." << endl;
cout << "Название позвоночника: " << nameSpine << endl;;
}
};
/*Создаем класс Mammal(Млекопитающее)*/
class Mammal
{
/*Объявляем переменную weightMammal(Вес млекопитающего) типа float
и объявляем указатель mammalFeatures(Особенности млекопитающего) на класс Spine c модификатором доступа private */
private:
float weightMammal;
Spine* mammalFeatures;
public:
/*Объявляем конструктор по умолчанию*/
Mammal()
{
/*Производим отладочную печать работы конструктора по умолчанию и инициализируем переменную weightMammal значением,
и выделяем память для mammalFeatures */
cout << "Конструктор по умолчанию Mammal" << endl;
weightMammal = 25.5;
mammalFeatures = new Spine[2];
}
/*Объявляем конструктор, который принимает в качестве параметров три переменные:
lengthSpine типа float, nameSpine типа string и weightMammal типа float.
В инициализации конструктора инициализируем переменную weightMammal полученным значением */
Mammal(float lengthSpine, string nameSpine, float weightMammal) : weightMammal(weightMammal)
{
/*Производим отладочную печать работы конструктора с параметрами, выделяем память для mammalFeatures,
передавая в качестве размерности 2 и вызываем setter`ы setLengthSpine и setNameSpine класса Spine,
передавая в качестве параметров переменные lengthSpine и nameSpine соответственно */
cout << "Конструктор с параметром Mammal " << endl;
mammalFeatures = new Spine[2];
mammalFeatures->setLengthSpine(lengthSpine);
mammalFeatures->setNameSpine(nameSpine);
}
/*Объявляем конструктор копирования Mammal, который принимает в качестве параметров объект Mammal
с именем cpyMammal.
В инициализации конструктора инициализируем переменную weightMammal скопированным значением */
Mammal(const Mammal& cpyMammal) : weightMammal(cpyMammal.weightMammal)
{
/*Производим отладочную печать работы конструктора копирования. Выделяем память для mammalFeatures, передавая в качестве размерности 1
Копируем поля объекта cpyMammal в mammalFeatures соответственно*/
cout << "Конструктор копирования Mammal" << endl;
this->mammalFeatures = new Spine[1];
this->mammalFeatures[0] = cpyMammal.mammalFeatures[0];
}
/*Объявляем перегруженный оператор присваивания*/
Mammal& operator=(const Mammal &mammal)
{
/*Производим отладочную печать работы перегруженного оператора присваивания*/
cout << "Перегруженный оператор присваивания Mammal" << endl;
/*Проверка на выделенность памяти. Если выделено-очищаем*/
if (this->mammalFeatures != nullptr)
{
delete[] this->mammalFeatures;
}
/*Выделяем память*/
this->mammalFeatures = new Spine[1];
/*Копируем поля объекта mammal в weightMammal и в цикле mammalFeatures соответственно*/
weightMammal = mammal.weightMammal;
this->mammalFeatures[0] = mammal.mammalFeatures[0];
/*Возвращаем текущий объект*/
return *this;
}
/*Объявляем деструктор*/
~Mammal()
{
/*Производим отладочную печать работы деструктора и освобождаем выделенную память для mammalFeatures*/
cout << "Деструктор Mammal" << endl;
delete[] mammalFeatures;
}
/*Объявляем setter для записи значения в private weightMammal*/
void setWeightMammal(float weightMammal)
{
this->weightMammal = weightMammal;
}
/*Объявляем getter для получения значения из private weightMammal*/
float getWeightMammal()
{
return weightMammal;
}
/*Метод вывода print полей класса*/
virtual void print()
{
/*Вызываем метод print из класса Spine*/
mammalFeatures->print();
cout << "Вес млекопитающего: " << weightMammal << " кг." << endl;
}
};
/*Объявляем класс Dog(Собака), который наследуется с видом наследования public от класса Mammal*/
class Dog : public Mammal
{
/*Объявляем переменную nameDogs типа string с модификатором доступа private*/
private:
string nameDogs;
public:
/*Объявляем конструктор по умолчанию, который,
в свою очередь, в инициализации конструктора инициализирует конструктор по умолчанию базового класса(Mammal)*/
Dog() : Mammal()
{
/*Производим отладочную печать работы конструктора по умолчанию и инициализируем переменную nameDogs*/
cout << "Конструктор по умолчанию Dog" << endl;
nameDogs = "Петруша";
}
/*Объявляем конструктор с параметрами, который принимает в качестве параметров четрые переменные:
lengthSpine типа float, nameSpine типа string и weightMammal типа float и nameDogs типа string,
в свою очередь, в инициализации конструктора инициализирует конструктор с параметрами базового класса(Mammal).
Также в конструкторе инициализации инициализируем nameDogs полученным значением*/
Dog(float lenghtSpine, string nameSpine, float weightMammal, string nameDogs) :
Mammal(lenghtSpine, nameSpine, weightMammal), nameDogs(nameDogs)
{
/*Производим отладочную печать работы конструктора с параметрами*/
cout << "Конструктор с параметрами Dog" << endl;
}
/*Объявляем конструктор копирования Dog, который принимает в качестве параметров объект Dog
с именем cpyPug.
В инициализации конструктора инициализируем конструктор базового класса(Mammal) и переменную nameDogs скопированным значением */
Dog(const Dog& cpyDog) : Mammal(cpyDog), nameDogs(cpyDog.nameDogs)
{
/*Производим отладочную печать работы конструктора копирования*/
cout << "Конструктор копирования Dog" << endl;
}
/*Объявляем деструктор класса Dog*/
~Dog()
{
/*Производим отладочную печать работы деструктора*/
cout << "Деструктор Dog" << endl;
}
/*Объявляем setter для записи значения в private nameDogs*/
void setNameDogs(string nameDogs)
{
this->nameDogs = nameDogs;
}
/*Объявляем getter для получения значения из private nameDogs*/
string getNameDogs()
{
return nameDogs;
}
/*Метод вывода print полей класса*/
void print()
{
/*Вызываем функция print базового класса(Mammal)*/
Mammal::print();
cout << "Кличка собаки: " << nameDogs << endl;
}
};
int main()
{
/*Объявляем переменные lengthSpine и weightMammal типа float и nameSpine типа string*/
float lengthSpine, weightMammal;
int agePugs;
int n = 0;
string nameSpine, nameDogs;
/*Устанавливаем русский язык*/
system("chcp 1251");
/*Очищаем окно консоли*/
system("cls");
cout << "Введите название позвоночника: ";
/*Считываем переменную nameSpine, введенной с клавиатуры*/
cin >> nameSpine;
cout << "Введите длину позвоночника: ";
/*Считываем переменную lengthSpine, введенной с клавиатуры*/
cin >> lengthSpine;
cout << "Введите вес млекопитающего: ";
/*Считываем переменную weightMammal, введенной с клавиатуры*/
cin >> weightMammal;
cout << "Введите кличку собаки: ";
/*Считываем переменную nameDogs, введенной с клавиатуры*/
cin >> nameDogs;
cout << "Сколько лет собаке? ";
/*Считываем переменную agePugs, введенной с клавиатуры*/
cin >> agePugs;
cout << "----------------------------------------------------------------------------" << "\n"
<< "----------------------------------------------------------------------------" << endl;
/*Объявляем экземпляр класса Pug с именем defaultPug, который вызывает конструктор по умолчанию*/
Pug defaultPug;
/*Выводим на экран получившиеся данные*/
defaultPug.print();
cout << "----------------------------------------------------------------------------" << "\n"
<< "----------------------------------------------------------------------------" << endl;
/*Объявляем экземпляр класса Pug с именем pugWithUserConstr, который вызывает конструктор с параметрами*/
Pug pugWithUserConstr(lengthSpine, nameSpine, weightMammal, nameDogs,agePugs);
/*Выводим на экран получившиеся данные*/
pugWithUserConstr.print();
cout << "----------------------------------------------------------------------------" << "\n"
<< "----------------------------------------------------------------------------" << endl;
/*Объявляем экземпляр класса Pug с именем cpyPug, который вызывает конструктор копирования*/
Pug cpyPug(defaultPug);
/*Выводим на экран получившиеся данные*/
cpyPug.print();
cout << "----------------------------------------------------------------------------" << "\n"
<< "----------------------------------------------------------------------------" << endl;
cout << "Введите количество элементов для массива ";
/*Считываем переменную n, введенной с клавиатуры*/
cin >> n;
/*Создаем массив указателей arr*/
Mammal **ar = new Mammal*[n];
/*Для тестирования объявляем экземпляр класса Pug *pugWithUserConstr2, который вызывает конструктор с параметрами */
Pug *pugWithUserConstr2 = new Pug(lengthSpine, nameSpine, weightMammal, nameDogs, agePugs);
/*Каждый элементу массива указателей инициализируем своими значениями*/
ar[0] = new Mammal();
ar[1] = new Dog();
ar[2] = pugWithUserConstr2;
/*Вызываем функцию printAll*/
printAll(ar, n);
