Туманные ошибки компоновщика в реализации иерархии классов C ++ - PullRequest
0 голосов
/ 30 октября 2011

Как требование присваивания для класса структур данных, я должен заставить работать следующую иерархию классов: http://www.brpreiss.com/books/opus4/

Исходный код также предоставляется, и сейчас я просто пытаюсь получить материал для компиляции. Это потребовало реорганизации определений классов в соответствующие им заголовочные файлы, перемещения реализации шаблона в файлы .inc и завершения фрагментов кода, которые не были реализованы. Я добился прогресса, но застрял на следующей ошибке (скомпилировано с VC ++):

1>main.obj : error LNK2019: unresolved external symbol "public: virtual __thiscall Iterator::~Iterator(void)" (??1Iterator@@UAE@XZ) referenced in function "public: virtual __thiscall NullIterator::~NullIterator(void)" (??1NullIterator@@UAE@XZ)

Я испробовал все обычные решения (устранение лишних, включая утверждения, очистка проекта и перекомпиляция и т. Д.), И я не уверен, куда идти. Как обсуждалось ранее, консенсус здесь заключается в том, что эта кодовая база действительно плохо спроектирована. Тем не менее, требование этого задания состоит в том, чтобы этот код работал, и я в глубине души собираю все это вместе и начинаю с нуля. Если это

Вот определение класса итератора в iterator.h

#ifndef ITERATOR_H
#define ITERATOR_H

#include "object.h"

class Iterator
{
public:

    virtual ~Iterator ();
    virtual void Reset () = 0;
    virtual bool IsDone () const = 0;
    virtual Object& operator * () const = 0;
    virtual void operator ++ () = 0;
};

class NullIterator : public Iterator
{
public:

    NullIterator () {}
    void Reset () {}
    bool IsDone () const { return true; }
    Object& operator * () const { return NullObject::Instance(); }
    void operator ++ () {}
};

#endif

Это все остальные заголовочные файлы, связанные с итератором:

#ifndef CONTAINER_H
#define CONTAINER_H

#include "object.h"
#include "visitor.h"
#include "iterator.h"
#include "ownership.h"

class Container : public virtual Object, public virtual Ownership
{
protected:

    unsigned int count;
    Container () : count(0) {}

public:

    virtual unsigned int Count () const { return count; }
    virtual bool IsEmpty () const { return Count () == 0; }
    virtual bool IsFull () const { return false; }
    //virtual HashValue Hash () const;
    virtual void Put (ostream&) const;
    virtual Iterator& NewIterator () const { return *new NullIterator (); }

    virtual void Purge () = 0;
    virtual void Accept (Visitor&) const = 0;
};

#endif

Стек и очередь также наследуются от контейнера, но, похоже, только стек использует Итератор:

#ifndef STACK_H
#define STACK_H

#include "linkList.h"
#include "container.h"

class Stack : public virtual Container
{
public:

    virtual Object& Top () const = 0;
    virtual void Push (Object&) = 0;
    virtual Object& Pop () = 0;
};

class StackAsLinkedList : public Stack
{
    LinkedList<Object*> list;

    class Iter;

public:

    StackAsLinkedList () : list() {}
    ~StackAsLinkedList() { Purge(); }

    //
    // Push, Pop and Top
    //
    void Push(Object& object);
    Object& Pop() override;
    Object& Top() const override;

    int CompareTo(Object const& obj) const;

    //
    // purge elements from, and accept elements onto, the list
    //
    void Purge();
    void Accept (Visitor&) const;

    friend class Iter;
};

class StackAsLinkedList::Iter : public Iterator
{
    StackAsLinkedList const& stack;
    ListElement<Object*> const* position;

public:

    Iter (StackAsLinkedList const& _stack) : stack(_stack) { Reset(); }

    //
    // determine whether iterator is pointing at null
    //
    bool IsDone() const { return position == 0; }

    //
    // overloaded dereference and increment operator
    //
    Object& operator*() const;
    void   operator++();

    void Reset() { position = stack.list.Head(); }
};

#endif

Если у кого-то есть понимание, оно будет высоко ценится. Я пытался решить эту ошибку за последние несколько часов и не добился никакого прогресса!

1 Ответ

1 голос
/ 30 октября 2011

Ошибка является ошибкой связывания, которая говорит о том, что вы не предоставили определение деструктору:

virtual ~Iterator();

Который вызывается через:

NullIterator::~NullIterator(void)

потому что NullIterator происходит от Iterator класса.

Решение: Вы должны предоставить определение деструктора Базового класса.

...