LINUX.ORG.RU

[C++][хочется странного]вызов метода


0

2

Язык: С++

Есть ли стандартые средсва языка, которые бы позволяли следующие действия: при вызове любого публичного метода объекта, после его отработки, вызывался дополнительный метод, общий для всего класса.

Например:

class A
{
public:
    void methodA();
    void methodB();
private:
    void methodC();
}

Чтоб после вызова и метода А и метода В и любого другого публичного метода, после его завершения вызывался еще и метод С.

Всем заранее спасибо за советы.

★★★★★

>Чтоб после вызова и метода А и метода В

man template method

и любого другого публичного метода

не выйдет. В плюсах нет искоробочных :before и :after методов, это вам не CLOS :)

yoghurt ★★★★★ ()
Ответ на: комментарий от yoghurt

>>Чтоб после вызова и метода А и метода В

man template method


Поясните, пожалуйста, вашу мысль.

P.S. С template'ами знаком не по наслышке.

trex6 ★★★★★ ()
Ответ на: комментарий от yoghurt

>В плюсах нет искоробочных :before и :after методов, это вам не CLOS

man template method

Как только не извращаются, лишь бы нормальными языками не пользоваться.

Love5an ()
Ответ на: комментарий от trex6

>P.S. С template'ами знаком не по наслышке.

С ними-то ты может быть и знаком, но паттерн «шаблонный метод» к плюсатым шаблонам никакого отношения не имеет.

Впрочем, шаблонный метод тут тоже не сильно поможет :)

yoghurt ★★★★★ ()

А если через классы? Ведь при конструировании класса гарантированно вызывается конструктор и деструктор.

Gorthauer ★★★★★ ()
Ответ на: комментарий от yoghurt

декоратор подразумевает наличие декоратора :) тут, как я понял, ТСу нужно всё в одном классе

я про то что это всё должно в одном классе работать как-то не вижу :)

ТС тебе как, строго один класс нужен или сойдёт обёрнутый декоратором?

shty ★★★★★ ()
Ответ на: комментарий от Gorthauer

легче в конец каждого метода вызов C() запихнуть :)

yoghurt ★★★★★ ()

Не знаю, этого ли хотел топикстартер, но

#include <iostream>

#define ENCLOSED_WITH(ptr2mmbr) method_encloser lol(*this, &ptr2mmbr)

class some_class {
public:
	void a();
	void b();

	class method_encloser {
		typedef void (some_class::*encloser) (void);

		some_class &obj_;
		encloser enc_;

	public:
		method_encloser (some_class &o, encloser e)
			: enc_(e),
			  obj_(o) {
		}
		~method_encloser () {
			(obj_.*enc_) ();
		}
	};

private:
	void c();
};

void some_class::a() {
	ENCLOSED_WITH (some_class::c);
	std::cout << "some_class::a" << std::endl;
}

void some_class::b() {
	ENCLOSED_WITH (some_class::c);
	std::cout << "some_class::b" << std::endl;
}

void some_class::c() {
	std::cout << "and in the end...!" << std::endl;
};

int main (int argc, char *argv[]) {
	some_class sc;
	sc.a();
	sc.b();
	return 0;
}

Но это ничем не лучше явного вызова метода в конце каждого метода :)

yoghurt ★★★★★ ()

Декоратор - много кода, который не особенно и поможет. Все равно придется вручную methodC дергать. (ну или я не до конца понял это паттернн).
Шаблонный метод - тоже немножко не то. Дело в том, что класс один, а методов и унего очень много.

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

Видимо все же лучший способ - дергать в конце каждого метода methodC().
А тем, кто будет поступать иначе - бить по рукам.

trex6 ★★★★★ ()
Ответ на: комментарий от trex6

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

Обсервер

yoghurt ★★★★★ ()

что только люди не делают, лишь бы аспекты не юзать.

JFreeM ★★★☆ ()
Ответ на: комментарий от yoghurt

Но это ничем не лучше явного вызова метода в конце каждого метода

а если теперь класс method_encloser в шаблон some_class вынести

shty ★★★★★ ()
Ответ на: комментарий от trex6

Декоратор - много кода, который не особенно и поможет. Все равно придется вручную methodC дергать. (ну или я не до конца понял это паттернн).

не поняли - факт :) посмотрите, там есть примеры кода на С++

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

shty ★★★★★ ()
Ответ на: комментарий от yoghurt

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

Обсервер

мне кажется обсервер не про то малец, в частности про «уведомления многих»

shty ★★★★★ ()
Ответ на: комментарий от yoghurt

Да, можно. А ещё можно всякие буст-лямбды-бинды задействовать +) Но легче от этого не на много станет

зато как +500 к ЧСВ :)

а если серьёзно, у меня есть ощущение, что Ваш подход можно переписать с использованием шаблонов таким образом, что получится весьма кошерное решение

shty ★★★★★ ()
Ответ на: комментарий от shty

Ну да, тут получается обсервер-наоборот (это ещё SASE называют в определённых кругах). Кутешные сигналы-слоты - те же SASE

yoghurt ★★★★★ ()
Ответ на: комментарий от shty

>у меня есть ощущение, что Ваш подход можно переписать с использованием шаблонов таким образом, что получится весьма кошерное решение

Возможно, но мне в конце рабочего дня лень об этом думать :)

Напишите, если сообразите что-нибудь

yoghurt ★★★★★ ()
Ответ на: комментарий от trex6

Видимо все же лучший способ - дергать в конце каждого метода methodC().

неканонично, потом надо будет дёргать methodX1() и Вы везде где это используется будете руками вызовы перебивать?

shty ★★★★★ ()
Ответ на: комментарий от yoghurt

Ну да, тут получается обсервер-наоборот (это ещё SASE называют в определённых кругах). Кутешные сигналы-слоты - те же SASE

тогда плюсую

shty ★★★★★ ()
Ответ на: комментарий от yoghurt

>у меня есть ощущение, что Ваш подход можно переписать с использованием шаблонов таким образом, что получится весьма кошерное решение

Возможно, но мне в конце рабочего дня лень об этом думать :)

Напишите, если сообразите что-нибудь

ну мне ещё сегодня часа 4 работать, а потом упасть и спать, так что я боюсь не сегодня :)

shty ★★★★★ ()
Ответ на: комментарий от yoghurt

> В плюсах нет искоробочных :before и :after

Были когда-то очень давно, пока Страуструп не отказался от них как невостребованных у пользователей С++.

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.