LINUX.ORG.RU

рефакторинг интерфейса класса на С++

 ,


0

1

Существует ли хороший способ не повторять declaration всех методов интерфейса в сабклассах?

Сейчас у меня есть abstract class

struct Node {
  Node *parent;
  std::vector<Node *> children;
  virtual void pretty_print(int indent) const = 0;
  virtual void accept(Visitor& v) = 0;
  virtual void typecheck(void) = 0;
  virtual Value *codegen(void) = 0;
};

и разные сабклассы имплементирующие этот интерфейс

// abstract class as well
struct Expression : public Node {
  map<string, Expression *> symtab;
  static Expression *parse(std::list<Token>& tokens);
};

struct LitDouble : public Expression {
  explicit LitDouble(double d) : val(d) {}
  virtual void accept(Visitor& v) { v.visit(this); }
  virtual void typecheck(void) {}
  virtual void pretty_print(int indent) const;
  virtual Value *codegen(void);
 static LitDouble *parse(std::list<Token>& tokens);
 private:
  double val;
};

struct LetExpr : public Expression {
  std::vector<Variable*> bindings;
  Expression *body;
  LetExpr(std::vector<Variable*> bs, Expression *b) : bindings(bs), body(b) {}
  virtual void accept(Visitor& v) { v.visit(this); }
  virtual void typecheck(void) {}
  virtual Value *codegen(void) {return NULL;}
  virtual void pretty_print(int indent) const;
  static LetExpr *parse(std::list<Token>& tokens);
};

ну и так далее. Четыре виртуальных метода повторяются во всех subclass declarations. Если есть более красивый способ указать что «class LetExpr implements interface Node», я хотел бы его использовать.


Если это одинаковые методы, то можно их реализацию вынести в промежуточный класс.

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

сабклассы имплементирующие

Хочется взять и...

и?

И научить говорить по-русски. Учить с особой жестокостью.

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

нет, имплементация у всех разная

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

Ах да.. если реализации разные, значит придётся их предоставлять в каждом классе, значит придётся сообщать об этом в описании класса.

mashina ★★★★★
()
Последнее исправление: mashina (всего исправлений: 1)
Ответ на: комментарий от mashina

нет слова упоротый в русском языке. Но мы сейчас о языке С++, так что не отвлекайся.

nokachi
() автор топика
Ответ на: комментарий от mashina

ну я хочу что-то типа

class Foo : this class implements interface Bar
{};

void Foo::typecheck(void) {
// implementation
}

void Foo::codegen(void) {
// implementation
}

вроде как ничто в С++ не мешает такое сделать (кроме, возможно, отсутствия такого синтаксиса)

nokachi
() автор топика
Ответ на: комментарий от nokachi

Ну сделай макрос.

#define MY_LITTLE_FUNCTIONS virtual void accept(Visitor& v); \
                            virtual void typecheck(void); \
                            virtual Value *codegen(void); \
                            virtual void pretty_print(int indent) const; 
Kuzy ★★★
()

Нет, нельзя. Ни в одном языке, ЕМНИП, потому что может только проблем добавить. Даже простой копипаст будет более эффективен.

А если у тебя реализации методов в двух и более наследниках одинаковы, то вынеси эту реализацию в родителя.

E ★★★
()

То, что ты хочешь, не нужно.

Не стоит гнаться за синтаксическим сахаром, внося при этом изменения в иерархию наследования.

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

Конечно, следует использовать исконно русское воплощение реализация.

ilammy ★★★
()

Дефолтное поведение для функций возможно?

1. Если да - выносишь его реализацию в базовый класс и убиваешь "=0".
2. Если нет - тогда что должно происходить при вызове не переопределенной фукнции? Ответ на этот вопрос и есть дефолтное поведение, запиши его на бумажку и переходи к п. 1.

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

В украинском повторения букв в заимствованных словах игнорируются, а в этих ваших стеклянных-деревянных-оловянных сам чёрт ногу сломит.

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

коммит = свершение, согласно Мицголу.

anonymous
()
Ответ на: комментарий от g0t0

я хочу чтобы каждый сабкласс переопределял (override) виртуальный метод. Поскольку это AST, у каждого типа нода будет свой код для тайпчека, кодогенерации итд. Дефолтное поведение не имеет смысла и неопределение какого-то метода должно приводить к ошибке компиляции.

nokachi
() автор топика
Ответ на: комментарий от anonymous

too much boilerplate. Но вообще да, это кажется неизбежно.

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