从我的driver.cpp调用派生类

时间:2017-02-18 22:04:17

标签: c++ class derived

我会非常感谢你的帮助。在我的计算机科学课上,我们被要求做一些我以前从未做过的事情,而且我不能很好地理解我的问题,甚至不知道谷歌的条款。

我们有三个文件。 lists.h,lists.cpp和driver.cpp

lists.h - 这是由教授提供的,不能被我改变。它是我将在......中推导出一个新类的基类。

lists.cpp - 这里我在类DLList中实现和双向链表。我之前做过dll,但不是这样。所以你会看到很多代码,尽管我无法测试任何代码。如果我的功能在这里错了,请不要担心,我只是想在......中创建一个双向链表。

driver.cpp - 这是我将用于在类DLList中测试我的函数的文件。

所以无论如何,我编译并得到......

g++ -c -g -Wall -std=c++11 driver.cpp
driver.cpp: In function ‘int main()’:
driver.cpp:12:5: error: ‘DLList’ was not declared in this scope
     DLList<int> mylist;
     ^

我理解错误。我之前看过这个,当main没有看到函数/ class / etc时。在更简单的代码中,这是因为它是在main之后。但在这里,我只是不知道如何解决它。显然,driver.cpp无法在lists.cpp中看到我的代码。

这是我的代码 -

不可改变的lists.h

template<typename E> class List {
private:
    void operator =(const List&) {}  // Protect assignment
    List(const List&) {}    // Protect copy constructor
public:
    List() {}  // Default constructor
    virtual  ~List() {} // Base destructor

    // Clear contents from the list, freeing memory
    virtual void clear() = 0;

    // Insert an element at the beginning of the list.
    virtual void prepend(const E& item) = 0;

    // Append an element at the end of the list.
    virtual void append(const E& item) = 0;

    // Extra credit: Insert an element at the current location, if possible;
    // return true if successful, false if there is no current element
    virtual bool insert(const E& item) = 0;

    // Extra credit: Remove and assign to item the current element, if possible;
    // return true if successful, false if there is no current element
    virtual bool remove(E& item) = 0;

    // Set the current position to the first element of the list, if possible;
    // return true if successful, false if list was empty
    virtual bool moveToStart() = 0;

    // Set the current position to the last element of the list, if possible;
    // return true if successful, false if list was empty
    virtual bool moveToEnd() = 0;

    // Move the current position one step right, if possible;
    // return true if successful, false if already at the end
    virtual bool next() = 0;

    // Move the current position one step left, if possible;
    // return true if successful, false if already at the beginning
    virtual bool prev() = 0;

    // Return a pointer to the current element (or NULL if none)
    virtual const E* getValue() const = 0;

    // Return total number of active nodes
    virtual int numActive() = 0;

    // Return total number of free nodes
    virtual int numFree() = 0;
};


// Factory function
template<typename E> List<E> *createList();

lists.cpp

#include "lists.h"
#include <cstddef>
#include <iostream>

using namespace std;

// Doubly linked list link node with freelist support
template <typename E> class Link {
private:
    // required by Lab 4
    static int free; // # of nodes free
    static int active; // # of nodes in use
    static Link<E> *freelist; // Reference to freelist head

    E element; // Value for this node
    Link *next; // Pointer to next node in list
    Link *prev; // Pointer to previous node

public:
    // Constructors
    Link(const E& it, Link *prevp=NULL, Link *nextp=NULL) {
        element = it;
        prev = prevp;
        next = nextp;
    }

    Link(Link *prevp =NULL, Link *nextp =NULL) {
        prev = prevp;
        next = nextp;
    }

    void * operator new(std::size_t) { // Overloaded new operator
        active++; // add to active count

        if (freelist == NULL) { // Create space
            return ::new Link; // ::new means use the standard c++ new operator
        }

        Link<E> *temp = freelist; // Can take from freelist
        freelist = freelist->next;
        free--; // will only subtract if we take from freelist

        return temp; // Return the link
    }

// Overloaded delete operator
    void operator delete(void* ptr) {
        free++;
        active--;
        // eliminate the Link being deleted from the active list
        Link *prev_tmp=((Link<E>*)ptr)->prev;
        Link *next_tmp=((Link<E>*)ptr)->next;
        prev_tmp->next=next_tmp;
        next_tmp->prev=prev_tmp;

        ((Link<E>*)ptr)->next = freelist; // Attach deleted Link to the head of the freelist
        freelist = (Link<E>*)ptr; // Now redefine the freelist to the new head
    }

    E get_data() const {
        return element;
    }

    E set_data(E& it) {
        element=it;
    }

    Link<E> *get_next() const {
        return next;
    }

    Link<E> *get_ptrb() const {
        return prev;
    }

    void set_next(Link<E> *new_next ) {
        next = new_next;
    }

    void set_prev(Link<E> *new_prev) {
        prev = new_prev;
    }

    int get_free() {
        return free;
    }

    int get_active(){
        return active;
    }

};
// The freelist head pointer is actually created here
template <typename E>
Link<E> *Link<E>::freelist = NULL;




template <typename E> class DLList: public List<E> {
private:
    Link<E> *head; // Pointer to list header
    Link<E> *tail; // Pointer to last element
    Link<E> *curr; // Access to current element

    void operator =(const DLList&) {}  // Protect assignment
    DLList(const DLList&) {}    // Protect copy constructor

public:
    // Default constructor
    DLList() {
        head=NULL;
        tail=NULL;
    }

    // Base destructor
    ~DLList() {
        //delete
    }

    // Clear contents from the DLList, freeing memory
    void clear() = 0;

    // Insert an element at the beginning of the DLList.
    void prepend(const E& item) {
        Link<E> *newLink = new Link<E>(item);

        if (head==NULL) {
            head=newLink;
            tail=newLink;
            curr=newLink;
        }
        else {
            newLink->set_next(head);
            head=newLink;
            curr=newLink;
        }

    }

    // Append an element at the end of the DLList.
    void append(const E& item) {
        Link<E> *newLink = new Link<E>(item);

        if (head==NULL) {
            head=newLink;
            tail=newLink;
            curr=newLink;
        }
        else {
            tail->set_next(newLink);
            tail=newLink;
            curr=newLink;
        }

    }

    void print_list() {
        if (head==NULL) {
            cout << "EMPTY LIST" << endl;
        }
        else {
            Link<E> *temp_ptr = head;
            int index=0;
            while(temp_ptr) {
                cout << "Link " << index++ << ": " << temp_ptr->get_data()  << endl;
                temp_ptr = temp_ptr->get_next();
            }
        }
    }

    // Extra credit: Insert an element at the current location, if possible;
    // return true if successful, false if there is no current element
    bool insert(const E& item) {
        if (curr==NULL) {
            return false;
        }
        else {
            Link<E> *newLink = new Link<E>(item);
            Link<E> *prev_ptr=curr->get_prev;
            Link<E> *next_ptr=curr->get_next();

            prev_ptr->set_next(curr);
            curr->set_prev(prev_ptr);

            next_ptr->set_prev(curr);
            curr->set_next(next_ptr);

            return true;
        }
    }

    // Extra credit: Remove and assign to item the current element, if possible;
    // return true if successful, false if there is no current element
    bool remove(E& item) {
        if (curr==NULL) {
            return false;
        }
        else {
            curr->set_data(item);
        }
    }

    // Set the current position to the first element of the DLList, if possible;
    // return true if successful, false if DLList was empty
    bool moveToStart() {
        if (head==NULL) {
            return false;
        }
        else {
            curr=head;
            return true;
        }
    }

    // Set the current position to the last element of the DLList, if possible;
    // return true if successful, false if DLList was empty
    bool moveToEnd() {
        if (head==NULL) {
            return false;
        }
        else {
            curr=tail;
            return true;
        }
    }

    // Move the current position one step right, if possible;
    // return true if successful, false if already at the end
    bool next() {
        if (curr==tail) {
            return false;
        }
        else {
            curr=curr->get_next();
            return true;
        }
    }

    // Move the current position one step left, if possible;
    // return true if successful, false if already at the beginning
    bool prev() {
        if (curr==head) {
            return false;
        }
        else {
            curr=curr->get_prev();
            return true;
        }
    }

    // Return a pointer to the current element (or NULL if none)
    const E* getValue() {
        if (curr==NULL) {
            return NULL;
        }
        else {
            curr->get_data();
        }
    }


    // ******** MIGHT HAVE TO GET THIS DATA FROM MULTIPLE SOURCES IF THE PTR IS NULL!!
    // BUG !
    // Return total number of active nodes
    int numActive() {
        return curr->get_active();
    }

    // ******** MIGHT HAVE TO GET THIS DATA FROM MULTIPLE SOURCES IF THE PTR IS NULL!!
    // BUG !
    // Return total number of free nodes
    int numFree() {
        return curr->get_free();
    }
};

// Explicit instantiation
template List<int> *createList();

driver.cpp

#include <iostream>
#include "lists.h"
using namespace std;

void uppercaseify(string& mystr) {
    for (auto& c: mystr)
        c = toupper(c);
}

int main() {
    createList<int>();
    DLList<int> mylist;
    return 0;
}

2 个答案:

答案 0 :(得分:0)

你是对的,错误是因为你的驱动文件中没有声明DLList类型。修复它的最简单方法是将list.cpp文件包含在驱动程序文件中

#include "list.cpp"

通常,当您使用具有相同名称的.h和.cpp文件时,它们应引用同一个类。因此,如果您在类练习之外编写此示例,则可能将list.cpp文件命名为DLList.h(请注意,模板类应位于.h文件中)。

答案 1 :(得分:0)

我认为你不应该在main()中显式实例化你的DLList类。这不起作用,因为你没有在“driver.cpp”中提供它的声明。

你应该做的是在“list.cpp”中实现工厂函数来返回动态分配的DLList实例:

template<> List<int> *createList() { return new DLList<int>; }

因此,对“driver.cpp”中的createList<int>()的调用将创建一个DLList实例,您可以通过List的界面进行测试:

int main() {
    // Create a DLList through factory function.
    List<int>* list = createList<int>();

    // Use the DLList through the List interface.
    list->append( ... );    

    // Finished with using list, free the memory
    delete list; list = nullptr;

    // Not necessary - we have created the DLList through factory function!
    // DLList<int> mylist;
    return 0;
}