C, PHP, VB, .NET

Дневникът на Филип Петров


* Класове, член-функции, конструктори и деструктори

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

Класовете позволяват да дефинираме нови типове данни. Един клас представлява описание на тип, включващ едновременно данни и функции, които ги обработват. Данните се наричат член-променливи, а функциите – член-функции. Дефиницията на един клас включва декларация на класа и дефиниции на член-функциите.

Декларацията на класа има следния синтаксис:

	class  <име-на-клас>{
		// Декларации на член-променливи
		// Декларации на член-функции
	};

Дефиницията на член-функция има следния синтаксис:

	<връщан-резултат> <име-на-клас>::<функция>(вх. парам.)
	{
		// Tяло на функцията
	}

За да се създаде обект, се използва името на класа като спецификатор за типа. Следният ред декларира обект obj:

	<име-на-клас> obj;

Достъпът до публичните елементи на класа се осъществява с операторът точка (.). Например ако класът myclass на обекта obj има член-функция func() и член-променлива int k, то ние можем да ги използваме директно или чрез указатели по следния начин:

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

	class myclass{
	public:
		void func();
		int k;
	};

	void myclass::func(){
		cout << k << endl;
	}

	void main(){
		myclass obj;
		obj.k = 5;
		obj.func();

		myclass *p;
		p = &obj;
		p->k = 12;
		p->func();
	}

Вече забелязахте, че видимите обекти се дефинират чрез „public:“. Възможно е да дефинирате и скрити обекти, които не могат да се достъпват директно:

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

	// Заедно с дефиницията на класа
	// създаваме обект obj от тип myclass
	class myclass{
	public:
		void func();
	private:
		int k;
	} obj;

	void myclass::func(){
		k = 5;
		cout << k << endl;;
	}

	void main()
	{
		// obj.k = 3; ще даде грешка:
		// error C2248: 'k' : cannot access private
		//        member declared in class 'myclass'

		// Чрез публичната функция обаче
		// имаме индиректен достъп до "k"
		obj.func();
	}

Конструктурът на един клас се извиква всеки път, когато се създава обект от този клас. Всякаква инициализация на данни, която е нужно да се извършим за даден обект, може да се изпълни автоматично от функцията конструктор. Той има същото име като името на класа, към който принадлежи, и не притежава тип на връщан резултат. Общият вид на конструктора е:

	<име-на-клас>::<име-на-клас>(<аргументи>){
		//Тяло на конструктор
	}

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

Деструкторът се извиква автоматично при разрушаването на обект от класа. Деструктора може да извежда съобщение за разрушаване на обекта или да освобождава заделената за обекта динамична памет. Деструкторът има същото име като класа, но предшествано от символа ~. Деструкторът не може да връща резултат и не може да има аргументи:

	~<име-на-клас>::<име-на-клас>(){
		//Тяло на деструктор
	}

Пример: Създава клас правоъгълник с публични елементи двете страни и функция за пресмятане на лицето. Дефинират се два конструктора на класа и един деструктор:

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

	class rectangle{
	public:
		// Два конструктора
		rectangle();
		rectangle(unsigned, unsigned);
		// Функциите могат да се описват и директно
		~rectangle(){
			cout << "Object destructed" << endl;
		}

		int area();
		unsigned sidea;
		unsigned sideb;
	};

	// Първият конструктор се извиква, без параметри
	// Ще поискаме потребителя да въведе страните
	rectangle::rectangle(){
		cout << "Enter side a: ";
		cin >> sidea;
		cout << "Enter side b: ";
		cin >> sideb;
	}

	// При втория конструктор ние сами сме указали
	// дължините на страните на правоъгълника
	rectangle::rectangle(unsigned a, unsigned b){
		sidea = a;
		sideb = b;
	}

	// Функцията, която връща лицето
	int rectangle::area(){
		return ((sidea) * (sideb));
	}

	void main(){
		// Създаваме нов обект и го инициализираме
		// чрез неговия конструктор
		rectangle *test = new rectangle();
		// Отпечатваме лицето на правоъгълника
		cout << "The area of the rectangle is: ";
		cout << test->area() << endl;
		// Извикваме деструктора и
		// освобождаваме паметта заета от обекта
		delete test;
		cout << endl << endl;

		// Тук създаваме директно правоъгълник
		// със зададени страни чрез втория конструктор
		rectangle *test2 = new rectangle(5,3);
		cout << "The area of the second rectangle is: ";
		cout << test2->area() << endl;
		delete test2;
	}

Както видяхте един клас може да има множество от конструктори, които се отличават по своите параметри. Това се нарича „предефиниране“ на функции. По абсолютно аналогичен начин е възможно да предефинирате член-функции на класа.

Задача: Създайте клас триъгълник с два конструктора. Първият е без параметри и изисква въвеждане на дължините на страните от потребителя (изисква се проверка на валидност на въведените данни, т.е. дали тези страни могат да са страни на триъгълник). Вторият конструктор създава триъгълник по директно зададени дължини на страни (но отново проверява за валидност на данните). Напишете функции за изчисляване на периметър и лице на така създадения триъгълник.

 



Добави коментар

Адресът на електронната поща няма да се публикува


*