从我的 driver.cpp 调用派生的 class

Calling a derived class from my driver.cpp

如果能提供一些帮助,我将不胜感激。在我的计算机科学 class 中,我们被要求做一些我以前从未做过的事情,而且我对我的问题的理解不够深入,甚至不知道 Google.[=16 的术语=]

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

lists.h - 这是教授提供的,我无法更改。这是我将在...

中派生出新的 class 的基础 class

lists.cpp - 这里我在 class DLList 中实现双向链表。我以前做过dll,但不是这样。所以你会在这里看到很多代码,尽管我无法测试任何代码。如果我的函数在这里有误,请不要担心,我只是想在 ...

中创建一个双向链表

driver.cpp - 这是我将用来测试我在 class 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;
     ^

我理解错误。当 function/class/etc 没有被 main 看到时,我以前见过这个。在更简单的代码中,这是因为它在 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;
}

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

#include "list.cpp"

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

我认为您不应该在 main() 中显式实例化您的 DLList class。这行不通,因为您在 "driver.cpp".

中没有可用的声明

您应该做的是将 "list.cpp" 中的工厂函数实现为 return 动态分配的 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;
}