Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 07.12.2010, 13:46   #1
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию реализация виртуальных функций не в своем классе

добрый день. такой вопрос.

есть базовый класс
Код:
class Base {
public:
	virtual void foo() = 0;

	void call()
	{
		foo();
	}
};
наследую от него
Код:
class A : public Base {
public:
};
но!!! я не хочу в классе A реализовывать чисто виртуальную функцию. хочу ее реализовать, например тут
Код:
class MyPolicy {
public:
	virtual void foo()
	{
		cout << "foo called" << endl;
	}
};
вопрос. как заставить класс A думать, что его вирт функция это Policy::foo? класс Base шаблонным делать нельзя MyPolicy так же ничего не должен знать о Base, т.е делать
Код:
class Policy : public Base {};
class A : public Policy {};
не хочется

как вариант, можно загнать в макрос перенаправление вызовов (A-->Policy). но хочется еще проще

загнал в макрос, получилось такое

Код:
#define CLASS_POLICY_REDIRRECTION(POLICY) \
protected: \
	inline void foo() { POLICY::foo(); } \
private:

class A : public Base, public MyPolicy {
    CLASS_POLICY_REDIRRECTION(MyPolicy)

public:
};
но не нравится мне это... хотя и самый логичный вариант (макрос спрятал рутину).
нормальный способ все еще ожидается


придумал. если кому вдруг интересно
Код:
#include <iostream>
#include <memory>

using namespace std;

class BasePolicy {
public:
	virtual ~BasePolicy() {}
	virtual void foo() = 0;
};

class Base {
public:
	Base(BasePolicy *b) : pol(b)
	{
		cout << "created" << endl;
	}

	virtual ~Base()
	{
		cout << "destroyed" << endl;
		delete pol;
	}

	void call()
	{
		pol->foo();
	}

	BasePolicy *getPol() { return pol; }

private:
	BasePolicy *pol;
};

class Policy1 : public BasePolicy {
public:
	void foo()
	{
		cout << "Policy1 foo called" << endl;
	}
};

class Policy2 : public BasePolicy {
public:
	void foo()
	{
		cout << "Policy2 foo called" << endl;
	}
};


class A : public Base {
public:
	A() : Base(new Policy1)
	{
		getPol()->foo();
	}
};

class B : public Base {
public:
	B() : Base(new Policy2)
	{
		getPol()->foo();
	}
};

int main()
{
	auto_ptr<Base> a(new A);
	auto_ptr<Base> b(new B);
	a->call();
	b->call();
	return 0;
}
всем спасибо за участие



ай нет, подсказали еще более лучший вариант) заменить диспетчеризацию на non virtual interface

Код:
#include <iostream>
#include <memory>

using namespace std;

class Base {
public:
	virtual void foo() = 0;

	void f()
	{
		foo();
	}
};

template<typename T>
class BaseImpl : public Base {
public:
	virtual void foo()
	{  
		static_cast<T *>(this)->call_foo();
	}
};

class Policy1 {
public:
	void call_foo()
	{
		cout << "Policy1 foo called" << endl;
	}
};

class Policy2 {
public:
	void call_foo()
	{
		cout << "Policy2 foo called" << endl;
	}
};

class A : public Policy1, public BaseImpl<A> {
};

class B : public Policy2, public BaseImpl<B> {
};

int main()
{
	(new A)->foo();
	(new B)->foo();
	return 0;
}
вот это уже идеально
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance

Последний раз редактировалось pproger; 07.12.2010 в 16:36.
pproger вне форума Ответить с цитированием
Старый 07.12.2010, 22:05   #2
sashonk
Форумчанин
 
Регистрация: 26.10.2009
Сообщений: 170
По умолчанию

рассказали бы тогда еще зачем такие конструкции использовать.
sashonk вне форума Ответить с цитированием
Старый 08.12.2010, 00:35   #3
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

для того, чтобы создавать дочерние классы от base с возможностью выбрать нужный policy (на стадии компиляции). так же именно этот policy должен был использоваться функциями класса base.
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Реализация функций поиска MaxMad Помощь студентам 0 04.12.2010 15:16
как создать динамический массив в своем классе? like_cloud Общие вопросы Delphi 6 24.11.2010 09:13
STL реализация алгоритма сортировки в классе Progsenya Общие вопросы C/C++ 0 09.09.2010 21:36
TCaption в своем классе ZotaC Gamedev - cоздание игр: Unity, OpenGL, DirectX 6 26.05.2010 19:21
Использование MediaPlayer в своем классе. Вадим Буренков Мультимедиа в Delphi 5 03.04.2009 17:16