Показать сообщение отдельно
Старый 02.07.2010, 17:19   #4
Samodelkin
Мастер
 
Регистрация: 12.01.2009
Сообщений: 983
Написано 390 полезных сообщений
(для 634 пользователей)
Ответ: Описатели (Descriptors)

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

это конечно хорошо, но в грамотно построенном приложении время создания и удаления объектов намного меньше времени просчёта основной логики, потому вводить чрезмерное ооп ради того чтобы в стеке не выделилось 10 кб раз в 10 секунд - оптимизации которые себя не оправдывают
А может там целая текстура в 50мб как ресурс. Вобщем то такую вещь можно и в менеджерах ресурсов исползовать.

кеш промахах и выравнивании
Это уже очень важно - если один объект и набор описателей будут все время находится в кеше то прирост производительности будет очень большой. Хотя конечно на последних цп кеши довольно большие - очень много объектов влезет и так.

Еще хочу обратить внимание на важную вещь - кеширование данных в том смысле что например если несколько указателей-описателей запрашивают одну и туже функцию с одинаковыми параметрами (например нахождение пути в одних и тех же точках) то можно же запомнить результат и не считать его каждый раз. Тут вообще много места для динамического программирования.

DescTest.cpp
#include "DescTest.h"

void Func() {

	/*
	======================================================================================
	Создадим указатель-описатель и сам объект.
	Вообще созданием объекта может заниматься другая функция
	или его можно получать из другой библиотеки.
	При присваивании указателю-описателю объекта счетчик указателей увеличивается на один.
	======================================================================================
	*/
	SmartPointerT<MyDesc, MyObject> sp(new MyObject());

	/*
	=================================================
	Настраиваем параметры для указателя-описателя sp.
	=================================================
	*/
	sp.desc.param1 = 'a';
	sp.desc.param2 = 10;
	sp.desc.param3 = 5.0f;
	sp.desc.PrintStat(); // Выводим параметры на экран

	/*
	==============================================================================
	Затем создадим второй указатель-описатель sp2 и скопируем параметры с sp один.
	Также можно копировать параметры и с описателей другого типа.
	Счетчик ссылок увелитися еще на один.
	==============================================================================
	*/
	SmartPointerT<MyDesc, MyObject> sp2(sp);
	sp.desc.param3 = 6.0f; // Изменим только третий параметр.
	sp.desc.PrintStat(); // Выведем на экран.

	/*
	========================================================
	Вызовы функций объекта через разные указатели-описатели.
	Тут можно активно использовать КЭШИРОВАНИЕ ДАННЫХ - 
	например один раз посчитал нахождение пути для sp и sp2
	может пользоваться готовым результатом.
	========================================================
	*/
	sp.SetParam(); // Применяем к объекту параметры дескриптора sp и работаем с объектом.
	sp.p.FuncOne();
	sp.p.FuncTwo();
	sp.SetParam(); // Применяем параметры sp2 и работаем (также можно попробовать сделать автоматическое применение параметров при вызове методов с текущего указателя).
	sp2.p.FuncThree();

	/*
	============================================
	Перед выходом из функции sp и sp2 удаляются,
	следовательно вызываются их деструкторы,
	следовательно удаляется объект MyObject.
	============================================
	*/
}

int main() {

	Func();

	// Остановим консоль.
	char a;
	std::cin >> a;	

	return 0;
}
DescTest.hpp

#include <stdio.h>
#include <iostream>


/************************************************

 Base

************************************************/

class MyDesc;

class Base {
public:
	unsigned int	count;

					Base() : count(0) {
						std::cout << "Base::Base" << std::endl;
					}
	virtual			~Base() {
						std::cout << "Base::~Base" << std::endl;
					}
};


/*************************************************

 MyObject

*************************************************/

class MyObject : public Base {
public:
	virtual	void	FuncOne() {}
	virtual void	FuncTwo() {}
	virtual void	FuncThree() {}

	void			SetParam(MyDesc& desc) {
						// Применяем параметры
					}
					
					MyObject() {
						std::cout << "MyObject::MyObject" << std::endl;
					}
	virtual			~MyObject() {
						std::cout << "MyObject::~MyObject" << std::endl;
					}
};


/*****************************************

 DescBase - MyDesc

*****************************************/

class DescBase {
public:
	virtual void	PrintStat() = 0;

					DescBase() {}
	virtual			~DescBase() {}
};

class MyDesc : public DescBase {
public:
	char			param1;
	int				param2;
	float			param3;

	virtual void	PrintStat() {
						std::cout << "PrintStat: " << param1 << ", " << param2 << ", "<< param3 << std::endl;
					}

	explicit		MyDesc() {}
	explicit		MyDesc(MyDesc& desc) {
						param1 = desc.param1;
						param2 = desc.param2;
						param3 = desc.param3;
					}
	virtual			~MyDesc() {}
};


/*****************************************

 SmartPointer (template)

*****************************************/

template<typename D, typename P>
class SmartPointerT {
private:
	void		operator =(SmartPointerT<D, P> sp) {}
	void*		operator new(size_t bytes) {}
	void		operator delete(void* address) {}
	void		operator delete(void* address, size_t bytes) {}

public:
	P&			p;
	D			desc;

	void		SetParam() {
					p.SetParam(desc);
				}

	explicit	SmartPointerT(P& object) : desc(), p(object) {
					p.count++;
					std::cout << "SmartPointerT::SmartPointerT\np.count = " << p.count << std::endl;
				}
	explicit	SmartPointerT(P* object) : desc(), p(*object) {
					p.count++;
					std::cout << "SmartPointerT::SmartPointerT\np.count = " << p.count << std::endl;
				}
	explicit	SmartPointerT(SmartPointerT<D, P>& sp) : p(sp.p), desc(sp.desc) {
					p.count++;
					std::cout << "SmartPointerT::SmartPointerT\np.count = " << p.count << std::endl;
				}
	virtual		~SmartPointerT() {
					p.count--;
					std::cout << "SmartPointerT::~SmartPointerT\np.count = " << p.count << std::endl;
					if(p.count == 0)
						delete &p;
				}
};
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
HolyDel (02.07.2010)