Это использование CRTP для статического полиморфизма, но без реализации производной функции.Компилируется как в gcc, так и в visual studio.Зачем? - PullRequest
3 голосов
/ 18 января 2011
#include <iostream>

template <class Derived>
class Base
{
public:
  void method1()
  {
    static_cast<Derived*>(this)->method1();
  }

  void method2()
  {
    static_cast<Derived*>(this)->method2();
  }
};

class Derived1: public Base<Derived1>
{
public:
  void method1()
  {
    std::cout << "Method 1 of Derived1 executed.\n";
  }
};

int main(int argc, char *argv[])
{
  Derived1 d1;
  d1.method1();
  d1.method2();
  return 0;
}

Следующий вопрос: как сделать этот тип безопасным? То есть, если кто-то забудет реализовать method2, я бы хотел, чтобы компилятор его перехватил. Я не хочу, чтобы это взрывалось во время выполнения.

Ответы [ 2 ]

8 голосов
/ 18 января 2011

Я думаю, причина этого в том, что если вы создаете этот код:

void method2()
{
  static_cast<Derived*>(this)->method2();
}

, где Derived не имеет реализации method2(), по сути будет прославленным саморекурсивным вызовом. Причина в том, что в Derived1 действительно есть функция-член под названием method2, а именно та, которая унаследована от базового класса.

Я попытался запустить этот код, и, конечно же, вызов method2 вызвал переполнение стека из-за саморекурсии.

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

2 голосов
/ 18 января 2011
  Derived1 d1;
  d1.method2();

Даже если Derived1 не определяет method2(), оно все равно получает его, наследуя BaseВот почему он компилируется и запускается.d1.method2() на самом деле вызывает Base::method2(), что снова вызывает себя.Это рекурсивный вызов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...