неопределенная ссылка

#c

#c

Вопрос:

у меня есть эти классы (и функции):

 template <class A>
class Factory{
  public:
    A (*binOp(void))(A,A);
};
int sum(int a, int b){
  return a   b;
}
class IntFactory : public Factory<int>{
  public:
    int (*binOp(void))(int,int){
      return amp;sum;
    }
};
template <class A>
class SpecializedList{
  protected:
    List<A>* list;
    Factory<A>* factory;
  public:
    SpecializedList(List<A>* list,Factory<A>* factory){
      this -> list = list;
      this -> factory = factory;
    }
    A sum(){
      return (list -> foldLeft(factory -> zero(), factory -> binOp()));
    }
};

// in main
SpecializedList<int>* sl = new SpecializedList<int>(join1 -> getList(),new IntFactory());
cout << sl -> sum() << endl;
  

Я получаю ошибки:

 /tmp/ccxdiwUF.o: In function  SpecializedList<int>::sum()':
list.cpp:(.text._ZN15SpecializedListIiE3sumEv[SpecializedList<int>::sum()] 0x19): undefined reference to  Factory::binOp()'
list.cpp:(.text._ZN15SpecializedListIiE3sumEv[SpecializedList::sum()] 0x2c):  `Factory::zero()'
collect2: ld returned 1 exit status
  

Кто-нибудь знает почему?
Я прогуглил соответствующую часть сообщений об ошибках, и, похоже, это связано с проблемами, когда код разбросан по разным файлам. На данный момент у меня есть все в одном файле.

Комментарии:

1. Используется virtual A (*binOp(void))(A,A) = 0 {} в базовом классе. Даже переопределенная функция должна где-то иметь тело.

2. @Benoit Но нет необходимости в теле, если вы сделаете его чисто виртуальным ... более того, это должно быть ответом.

3. @Konrad: На самом деле, текст неверен. Определение для чисто виртуальной функции написано отдельно.

4. Я должен признаться, что я был довольно смущен этим объявлением, но я думаю, что я понял это. binop это функция, которая не принимает аргументов и возвращает указатель на функцию, которая принимает два int s и возвращает и int . Верно? Синтаксис указателя на функцию действительно отвратительный, если вы спросите меня.

Ответ №1:

Две проблемы:

  • Factory не определяет функцию binOp() .
  • У Factory даже нет функции zero() .

Решение:

  • Сделайте функцию binOp() чисто виртуальной функцией в Factory , указав чистый спецификатор как:

      virtual A (*binOp(void))(A,A) = 0; //"=0" is called pure-specifier
    //^^^^^^ this makes the function virtual
      

    Нет необходимости определять это сейчас (что касается ошибки компоновщика). При желании вы также можете определить это.

  • Объявите функцию zero() на заводе. Если вы не делаете это чисто виртуальным, то должны определить это.

Комментарии:

1. Я думаю, вам нужно добавить virtual к этому чисто виртуальному объявлению, не так ли?