C++, хочу composition вместо inheritance, но с virtual methods...
Вот я отнаследовался от миксина который хз где объявленНе наследуйся от неизвестно где объявленного!
Ты к съезду, что ли, готовишься, делегатов ищешь?
Кстати, в плюсах нет чего-нибудь вроде сишарпового указания метод какого интерфейса ты оверрайдишь?Бля, явное управление сборщиком — это по-настоящему круто!
просто пиши комменты, мол вот здесь идут оверрайды такого-то предка.
Бля, явное управление сборщиком — это по-настоящему круто!По-моему ты принял просроченные вещества!
System.GC.SuppressFinalize(this);
А так, это же низкоуровневый код для общения с ОС в котором это нужно и который должен быть спрятан внутри библиотечного кода. В обычном коде файналайзеры вообще не должны использоваться, как бы, ну и SuppressFinalize тоже.
Так и покруче штуки могут быть, например, когда пишешь ну совсем низкоуровневый код который работает с хэндлами (как IntPtr) и почему-то не подходит заранее написанный SafeHandle, то нужно дико аккуратно в конец практически каждого метода вставлять GC.KeepAlive(this). Потому что GC же не знает что этот IntPtr это на самом деле внешний ресурс лайфтаймом которого ты весьма озабочен, и легко может убить твой объект и вызвать его деструктор (который закроет хэндл) в середине твоего метода который уже достал хэндл из this, но ещё не вызвал какой-нибудь нативный метод с ней.
http://ideone.com/C72Jh9
class A
{
void f {}
};
class B: private A
{
};
class C: B, private A
{
void g
{
f;
}
};
prog.cpp:10:7: warning: direct base ‘A’ inaccessible in ‘C’ due to ambiguity [enabled by default]
prog.cpp: In member function ‘void C::g’:
prog.cpp:14:9: error: reference to ‘f’ is ambiguous
prog.cpp:3:10: error: candidates are: void A::f
prog.cpp:3:10: error: void A::f
Если кто не заметил, B наследуется от А приватно, но компилятор по всей видимости не учитывает эту незначительную деталь когда резолвит методы. Что за долбанутый язык всё же!
Ну и хорошо, это оно фактически наставило меня на путь истенный, как бы намекая что нужно не выпендриваться и делать через композицию!
ну да, в плюсах все эти механизмы поиска и сокрытия имен не обращают внимания на уровень доступа.
Оставить комментарий
bleyman
Мне нужно сделать небольшой хелпер-класс который имплементирует некую часто встречающуюся функциональность, например, засовывает мессаги в буфер и когда их там набирается тыща штук проверяет нет ли дубликатов за один запрос к базе данных.Мне что-то в последнее время дико не нравится наследование своей магичностью. Вот я отнаследовался от миксина который хз где объявлен и у меня магически появилось несколько новых методов, а вот эти виртуальные методы на самом деле оверрайдят методы миксина, и никак это не поймёшь и даже не заподозришь пока не пойдёшь и не посмотришь его объявление (угадав, какой именно из миксинов).
Плюс я бы хотел назвать методы хелпера так же, как методы самого инпут плагина (которые он оверрайдит у своего интерфейса, begin_input/input_message/end_input но это будет ваще полный п-ц.
С другой стороны если использовать композицию, то всё зашибись, буду спокойно вызывать input_helper.begin_input и всем всё понятно с первого взгляда.
Но. Мне как бы нужно всё же custom behaviour — вот с этими дубликатами, хочется чтобы хелпер всегда спрашивал у меня как получить unique key для мессаги (потому что я их скармливаю ему в нескольких местах кода и иногда нужно особое поведение если нашлись/не нашлись дубликаты.
Ну и как это сделать наиболее вменяемым образом?
Я пока думаю завести полу-абстрактный интерфейс IHelperCallback с этими методами, наследоваться от него и имплементировать нужные в плагине, затем передавать this в конструктор хелпера. Кривовато, конечно, но магея сведена к абсолютно необходимому минимуму.
Передавать пойнтеры на мемберы же будет совсем жуткий геморрой, да?
Кстати, в плюсах нет чего-нибудь вроде сишарпового указания метод какого интерфейса ты оверрайдишь?