Не так давно (меньше полугода) программирование стало моим хобби. Выбрал язык С++ и как в любом учебном процессе, понять нужную информацию бывает иногда очень сложно.

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

Ну… поехали.

Прежде всего представим, что вы директор небольшой фирмы, которая занимает строительством и сбытом многоквартирных домов. Вот, вы в очередной раз построили дом и минимальная единица в этом доме — отдельная квартира.

Создаем класс — квартира:

// Площадка
class level{
private:
	flat* ptrflat[4]; // Массив указателей на 4-ре квартиры
public:				  
	level (){
		for (int i(0); i!=4; i++){
			ptrflat[i] = new flat; // Создаем каждую квартиру.
		}
	}

	int get_S(){
		int summa (0); 
		for (int i(0); i!=4; i++){
			summa += ptrflat[i] -> get_S(); // Получаем площадь квартиры.
		}
		return summa; // Возвращаем сумму площадей квартиры.
	}
	~level (){
		delete [] ptrflat;
	}
}; // end level;

Далее наш дом состоит из этажей. В нашем доме их будет 10.

class externy{
// Подъезд
class externy{
private:
	level* ptrlevel[10]; // 10 этажей, по 4 квартиры в каждом.
public:
	externy (){
		for (int i(0); i!=10; i++){
			ptrlevel[i] = new level; // Создаем этажи.
		}
	}
	int get_S(){
		int summa (0); 
		for (int i(0); i!=10; i++){
			summa += ptrlevel[i] -> get_S();
		}
		return summa;
	}
	~externy(){
		for (int i(0); i!=10; i++){
			ptrlevel[i] -> ~level(); // Освобождаем память.
		}
		delete [] ptrlevel; // Удаляем массив.
	}
}; // end amount;

И наконец, мой… вернее твой дом состоит из трех подъездов :)

// Весь дом
class sum{
private:
	externy* ptrexterny[3]; // 3 подъезда по 10 этажей, по 4 квартиры на каждом.
public:
	sum (){
		for (int i(0); i!=3; i++){
			ptrexterny[i] = new externy; // Создаем подъезды.
		}
	}
	int get_S(){
		int summa (0); 
		for (int i(0); i!=3; i++){
			summa += ptrexterny[i] -> get_S();
		}
		return summa;
	}
	~sum(){
		for (int i(0); i!=3; i++){
			ptrexterny[i] -> ~externy(); // Освобождаем память.
		}
		delete[] ptrexterny;
	}
};// end sum;

Фуф, все классы связали и заключительная нота — главная функция:

int main(){
	SetConsoleCP (1251);
	SetConsoleOutputCP (1251);

	
	sum myhousrs; // Создаем объект.
	const int cost (70000); // Цена квадратного метра.
	
	std::cout << "Площадь (м2): " << myhousrs.get_S() 
<< " суммарная стоимость: " << cost * myhousrs.get_S() << std::endl;

	system ("pause");
	return NULL;
};

Полный код:

#include <Windows.h>
#include <iostream>


// Класс квартиры.
class flat{
private:
	double S; // площадь
public:
	flat (){
		S = rand()%40+10; // рандомная площадь квартиры
	}
	int get_S(){
		return S; // Вернем значение площади, когда нам это будет необходимо.
	}
}; // end flat;

// Площадка
class level{
private:
	flat* ptrflat[4]; // Массив указателей на 4-ре квартиры
public:				  
	level (){
		for (int i(0); i!=4; i++){
			ptrflat[i] = new flat; // Создаем каждую квартиру.
		}
	}

	int get_S(){
		int summa (0); 
		for (int i(0); i!=4; i++){
			summa += ptrflat[i] -> get_S(); // Получаем площадь квартиры.
		}
		return summa;
	}

	~level (){
		delete [] ptrflat;
	}
}; // end level;

// Подъезд
class externy{
private:
	level* ptrlevel[10]; // 10 этажей, по 4 квартиры в каждом.
public:
	externy (){
		for (int i(0); i!=10; i++){
			ptrlevel[i] = new level; // Создаем этажи.
		}
	}

	int get_S(){
		int summa (0); 
		for (int i(0); i!=10; i++){
			summa += ptrlevel[i] -> get_S();
		}
		return summa;
	}

	~externy(){
		for (int i(0); i!=10; i++){
			ptrlevel[i] -> ~level(); // Освобождаем память.
		}
		delete [] ptrlevel; // Удаляем массив.
	}
}; // end amount;

// Весь дом
class sum{
private:
	externy* ptrexterny[3]; // 3 подъезда по 10 этажей, по 4 квартиры на каждом.
public:
	sum (){
		for (int i(0); i!=3; i++){
			ptrexterny[i] = new externy; // Создаем подъезды.
		}
	}

	int get_S(){
		int summa (0); 
		for (int i(0); i!=3; i++){
			summa += ptrexterny[i] -> get_S();
		}
		return summa;
	}

	~sum(){
		for (int i(0); i!=3; i++){
			ptrexterny[i] -> ~externy(); // Освобождаем память.
		}
		delete[] ptrexterny;
	}

};// end sum;



int main(){
	SetConsoleCP (1251);
	SetConsoleOutputCP (1251);

	
	sum myhousrs; // Создаем объект.
	const int cost (70000); // Цена квадратного метра.
	
	std::cout << "Площадь (м2): " << myhousrs.get_S() << " суммарная стоимость: " << cost * myhousrs.get_S() << std::endl;

	system ("pause");
	return NULL;
};

Немного о принципе действия:

Из главной функции мы «заходим» в конструктор класса SUM, который в свою очередь создает несколько классов EXTERNY, EXTERNY создает несколько классов LEVEL, а LEVEL создает несколько классов типа FLAT.

В следующей части постараюсь объяснить наглядно, приведя рисунки и пояснить более точно принцип действия программы :)
Поделиться с друзьями
-->

Комментарии (3)


  1. maaGames
    10.04.2017 15:46
    +2

    > ptrlevel[i] -> ~level(); // Освобождаем память.

    Это не освобождение памяти, это вызов деструктора, а память осталась занята.

    > delete [] ptrlevel; // Удаляем массив.

    Это вообще крашит программу, потому что ptrlevel[10] — массив на стэке.


  1. Karroplan
    10.04.2017 15:48
    +1

    простой вопрос — а если построили 12-этажку? Да и деструкторы у вас все кривые (


  1. Shtucer
    10.04.2017 16:02

    но все еще слабо понимают, где и как этот указатель можно использовать

    Я так понимаю, это будет долгий цикл статей, рассказывающий как не надо использовать указатели. В конце завершающей стать будет написано что-то вроде: "а во всех остальных случаях укзатели это очень удобный инструмент, пользуйтесь с осторожностью"? Обучение методом от противного, так сказать. Это будет ооочень долгий цикл статей. Боюсь, не доживу.