Как правильно наследовать класс?

289
03 апреля 2017, 07:59

Создаю класс Stack, который наследует LinkedList, но выдает ошибку еще при компиляции, подскажите, в чем проблема.

Ошибка:

"D:\CLion 2016.3.3\bin\cmake\bin\cmake.exe" --build D:\workspaceForCLion\StudyProj\cmake-build-debug --target StudyProj -- -j 2 Scanning dependencies of target StudyProj [ 50%] Building CXX object CMakeFiles/StudyProj.dir/main.cpp.obj In file included from D:\workspaceForCLion\StudyProj\main.cpp:2:0: D:\workspaceForCLion\StudyProj\Stack.h:8:35: error: expected class-name before '{' token class Stack : protected LinkedList{ ^ D:\workspaceForCLion\StudyProj\Stack.h: In instantiation of 'void Stack::push(T) [with T = int]': D:\workspaceForCLion\StudyProj\main.cpp:6:17: required from here D:\workspaceForCLion\StudyProj\Stack.h:43:11: error: 'class Stack' has no member named 'prepend' this->prepend(data); ~~~~~~^~~~~~~ D:\workspaceForCLion\StudyProj\Stack.h: In instantiation of 'T Stack::pop() [with T = int]': D:\workspaceForCLion\StudyProj\main.cpp:12:23: required from here D:\workspaceForCLion\StudyProj\Stack.h:49:11: error: 'class Stack' has no member named 'remove' this->remove(res); ~~~~~~^~~~~~ CMakeFiles\StudyProj.dir\build.make:61: recipe for target 'CMakeFiles/StudyProj.dir/main.cpp.obj' failed mingw32-make.exe[3]: * [CMakeFiles/StudyProj.dir/main.cpp.obj] Error 1 mingw32-make.exe[2]: [CMakeFiles/StudyProj.dir/all] Error 2 CMakeFiles\Makefile2:66: recipe for target 'CMakeFiles/StudyProj.dir/all' failed CMakeFiles\Makefile2:78: recipe for target 'CMakeFiles/StudyProj.dir/rule' failed Makefile:117: recipe for target 'StudyProj' failed mingw32-make.exe[1]: [CMakeFiles/StudyProj.dir/rule] Error 2 mingw32-make.exe: * [StudyProj] Error 2

LinkedList.h

#pragma once
#include <iostream>
using namespace std;
    template<class T>
    class LinkedList {
    private:
        struct node {
            T data;
            node *next;
        } *head;
    public:
        LinkedList();
        ~LinkedList();
        void append(T data);
        void prepend(T data);
        void remove(T data);
        void clear();
        void output();
    };
template <class T>
LinkedList<T>::LinkedList() {
    head=NULL;
};
template <class T>
LinkedList<T>::~LinkedList() {
    node *p, *q;
    p = head;
    if(p==NULL) return;
    while(p){
        q = p->next;
        delete p;
        p = q;
    }
}
template <class T>
void LinkedList<T>::prepend(T data){
    node *p, *q;
    if(head==NULL){
        head = new node;
        head->data = data;
        head->next = NULL;
        return;
    }
    p = this->head;
    q = new node;
    q->data = data;
    q->next = p;
    this->head = q;
}
template <class T>
void LinkedList<T>::remove(T data){
    node *p, *q;
    if(head == NULL) return;
    p = head;
    while(p){
        if(p->data == data){
            q->next = p->next;
            delete p;
            return;
        }
        q = p;
        p = p->next;
    }
}
template <class T>
void LinkedList<T>::clear(){
    node *p, *q;
    if(head==NULL) return;
    p = head;
    while(p){
        q = p->next;
        delete p;
        if(q != head){
            head = NULL;
            return;
        }
        p = q;
    }
}
template <class T>
void LinkedList<T>::append(T data){
    node *p, *q;
    if(head==NULL){
        head = new node;
        head->data = data;
        head->next = NULL;
        return;
    }
    p = head;
    while(p->next!=NULL)
        p = p->next;
    q = new node;
    q->data = data;
    q->next = NULL;
    p->next = q;
}
template <class T>
void LinkedList<T>::output() {
    if(this->head == NULL){
        cout << "List is empty" << endl;
        return;
    }
    node *p;
    p = this->head;
    while (p != NULL) {
        cout << p->data << " -> ";
        p = p->next;
    }
    cout << "NULL" << endl;
}

Stack.h

#pragma once
#include <iostream>
#include "LinkedList.h"
template<class T>
class Stack : protected LinkedList{
private:
    struct node {
        T data;
        node *next;
    } *top;
    node *down;
public:
    Stack();
    ~Stack();
    void push(T);
    T pop();
    T peek();
    void output();
};
template <class T>
Stack<T>::Stack() {
    top = down = NULL;
};
template <class T>
Stack<T>::~Stack() {
    node *p, *q;
    p = top;
    if(p==NULL) return;
    while(p){
        q = p->next;
        delete p;
        p = q;
    }
};
template <class T>
void Stack<T>::push(T data){
    this->prepend(data);
}
template <class T>
T Stack<T>::pop(){
    T res = this->top->data;
    this->remove(res);
    return res;
}
template <class T>
T Stack<T>::peek(){
    return this->top->data;
}
template <class T>
void Stack<T>::output(){
    this->output();
}

main.cpp

#include <conio.h>
#include "Stack.h"
int main(int argc, char** argv) {
    Stack<int> stack;
    stack.push(1);
    stack.push(2);
    stack.push(3);
    stack.push(4);
    stack.push(5);
    cout << stack.pop();
    _getch();
    return 0;
}
Answer 1

Класс LinkedList шаблонный, он по сути создается только в момент использования с каким-то типом. Поэтому наследование должно выглядеть

template<class T>
class Stack : protected LinkedList<T> {
    // something
};
Answer 2

У вас в коде нет класса LinkedList. У вас в коде есть шаблон класса LinkedList с одним параметром. Использовать этот шаблон класса там, где требуется именно класс, можно только при условии указания аргументов шаблона. У вас же написано

template<class T>
class Stack : protected LinkedList {

Это не является корректным объявлением, ибо аргументы шаблона LinkedList не указаны. Что вы имели в виду под этим LinkedList? Скорее всего LinkedList<T>? Тогда так и пишите.

Отдельное недоумение вызывает то, что вы вдруг зачем-то явно взялись реализовывать удаление элементов в деструкторе Stack<T>::~Stack(), при том что деструктор LinkedList и так сам это делает. Непонятно также, почему деструктор LinkedList не пользуется собственным методом clear(), а вместо этого выписывает удаление с нуля. (Хотя надо признать, что в методе clear написана какая-то белиберда.)

READ ALSO
Qt connect с разными аргументами

Qt connect с разными аргументами

Здравствуйте! Как сделать connect с разными аргументами (qint64 и int)?

231
Как установить библиотеку Qt?

Как установить библиотеку Qt?

Всем здравствуйтеНедавно начал изучать С++, и захотелось написать самое простое приложение с графическим окном

299
HasPyRuCP+: Runtime Error

HasPyRuCP+: Runtime Error

Недавно появился язык HasPyRuCP+Написал программу которая принимает от пользователя граф и две вершины

240
Юнит-тесты для JS

Юнит-тесты для JS

Необходимо изучить юнит-тестированиеКакие из фреймворков простые для понимания и написания самих тестов?

241