Вопрос больше похож на теоретический.
Предисловие. посетителей картина:Перегрузка и этот указатель
class Visitor
{
public:
virtual void VisitElementA(const ElementA& obj) = 0;
virtual void VisitElementB(const ElementB& obj) = 0;
};
class Element
{
public:
virtual void Accept(Visitor& visitor) = 0;
};
class ElementA : public Element
{
public:
void Accept(Visitor& visitor) override { visitor.VisitElementA(*this); }
};
class ElementB : public Element
{
public:
void Accept(Visitor& visitor) override { visitor.VisitElementB(*this); }
};
Это VisitElementA (Const Elementa & объекта) выглядит немного некрасиво, поэтому использование перегрузки можно переписать так:
class Visitor
{
public:
virtual void Visit(const ElementA& obj) = 0;
virtual void Visit(const ElementB& obj) = 0;
};
И теперь у нас есть два одинаковые реализаций метода принятия в элементах ElementA и ElementB:
void Accept(Visitor& visitor) override { visitor.Visit(*this); }
И такой код должен быть добавлен в ElementC, ElementD и т. Д. (Если есть)
Вопрос: Как избежать этого дублирования?
Наивное решение поместить Accept реализации внутри класса Element (или какой-либо другой промежуточного класса) не будет работать из-за этот указатель будет указывать на объект, чтобы объект класса Element, а не Elementa или ElementB, и, таким образом, в лучшем случае мы получим ошибку компиляции или даже неправильное поведение (если будет некоторый перегруженный метод Visit для Element).
Насколько я понимаю, проблема заключается в попытке сочетать функции компиляции и времени выполнения. Но может существовать какое-то решение на основе шаблонов или новая функция C++ 11 или что-то еще?
Одно замечание: я был бы признателен, если вы не предложите решение с «магией макросов» :).
Да, об этом я тоже думал, когда заметил сбой смеси. Но CRTP не будет работать, если есть другое наследование, более глубокое, чем ElementA, т. Е. Когда у вас есть класс ElementC: ElementA. Вот почему я написал, что «смешивание должно знать тип FINAL» – quetzalcoatl
Это определенно сработает, я использовал такой подход при реализации обобщенного шаблона Singleton (просто не знал, что он имеет имя) и (такой позор :)) забудь об этом. Благодарю. Но если вы не возражаете, я подожду еще некоторое время: может быть, кто-то знает лучшее решение. – cody
Обратите внимание, что приведение не обязательно безопасно – newacct