* Наследяване

Публикувано на 14 ноември 2008 в раздел С/C++.

Когато един клас наследява друг се използва общата форма:

	class <производен-клас>:<тип-достъп> <име-базов-клас> {
		//...
	};

Типът достъп е една от трите ключови думи: public, private или protected. Разликата между тях е:
- Ако наследяването е тип public, то на производния клас се допуска достъп до членовете на неговия собствен клас, на неговия базов клас и на функции, външни за класовете.
- Ако наследяването е тип protected, то се допуска достъп до членовете на неговия собствен клас, на неговия базов клас, но не се допуска достъп на функции външни за класа.
- Ако наследяването е тип private, то производният клас няма достъп до private елементите на базовия клас и външни функции.

Ако е необходимо да се предаде аргумент на конструктора на базовия клас, то всички необходими аргументи за базовия и за производния клас се предават на конструктора на производния клас. Като се използва разширената форма на декларация на конструктора на производния клас, могат да се предадат съответните аргументи и към базовия клас:

	<производен конструктор>(списък аргументи):<базов-клас>(списък аргументи) {
		//тяло на конструктора на производния клас
	}

Пример: Дефинираме базов клас vehicle и два производни класа – car и truck:

	#include "stdafx.h"
	#include "iostream.h"

	// Базов клас превозно средство
	class vehicle {
		int num_wheels;
		int weight;

		public:
		// Конструктор
		vehicle(int w, int r)
		{
			num_wheels = w;
			weight = r;
		}
		// Функция, която отпечатва броя гуми
		// и тежестта на превозното средство
		void showv(){
			cout << "Wheels: ";
			cout << num_wheels;
			cout << endl;
			cout << "Weight: ";
			cout << weight;
			cout << endl;
		}
	};

	// Клас кола наследява клас превозно средство
	class car : public vehicle {
		// Добавя се нова променлива
		int passengers;

		public:
		// Конструктора се предефинира, така че
		// да приема три аргумента. Два от тях се
		// предават като аргументи на конструктора
		// на базовия клас
		car(int p, int w, int r) : vehicle(w, r)
		{
			passengers = p;
		}

		// В нова функция show извикваме вече
		// съществуващата в базовия клас функция
		// showv и добавяме функционалност
		void show()
		{
			showv();
			cout << "Passengers: ";
			cout << passengers;
			cout << endl;
		}
	};

	// Аналогично създаваме втори производен клас
	class truck : public vehicle {
		int loadlimit;

		public:

		truck(int l, int w, int r) : vehicle(w, r)
		{
			loadlimit = l;
		}

		void show(){
			showv();
			cout << "Loadlimit: ";
			cout << loadlimit;
			cout << endl;
		}
	};

	int main()
	{
		car c(5, 4, 1200);
		truck t(30000, 12, 3000);
		cout << "Car: " << endl;
		c.show();
		cout << endl << "Truck " << endl;
	 	t.show();
		return 0;
	}

Задача: Съставете базов клас триъгълник с четири елемента дължина на съответните страни и конструктори, който инициализират и валидират входните данни. Направете функция на базовия клас за намиране на лицето на триъгълника по хереоновата хормула. Създайте:
- Производен клас „равнобедрен триъгълник“ и предефинирайте конструктора.
- Производен клас „равностранен триъгълник“ и предефинирайте конструктора. Напишете втора функция за изчисляване на лицето на триъгълник, която използва директно формулата за лице на равностранен триъгълник: a*a*sqrt(3)/4.



3 коментара за “Наследяване”

 
  1. p0:

    Интересно…опитах примерът 1:1, който е за колата и камиона и в полето за loadlimit ми излезе „-858993460″, а всичко изглежда вярно. Имате ли представа от какво би могла да се получи такава грешка?

     
  2. Филип Петров:

    Ако ти излиза това число, то най-вероятно променливата НЕ е инициализирана (няма присвоена стойност). В случая ти се извежда стойността по подразбиране.

    Тази променлива „loadlimit“ я има само и единствено в клас „truck“ и се инициализира от конструктора му:
    truck(int l, int w, int r) : vehicle(w, r) {
    loadlimit = l;
    }

    Щом ти се показва тази стойност, значи просто тази инициализация НЕ е станала правилно.

    Вариант 1 – имаш променлива loadlimit на още едно място и става объркване коя от двете да се инициализира. Ето например как може да стане това:
    truck(int l, int w, int r) : vehicle(w, r) {
    int loadlimit = l; // ГРЕШКА!!!
    }

    Вариант 2 – класа не се инициализира правилно в main метода (предава се невалидна стойност, например null)…

    Ако намериш грешката моля пиши…

     
  3. p0:

    Аз в main бях инициализирала променливата по същия начин както Вас тук в примера. Създадох обект от типа на класа truck – t(30000,12,3000). Вероятно се е получило някакво дублиране тогава, или компилаторът се е бъгнал, защото сега излезе коректна стойност за loadlimit. Иначе в класа truck си я бях декларирала в private, а в констуктора само я инициализирах и така. Благодаря.

     

RSS за коментарите

Пусни коментар