【问题标题】:Why this isEmpty() from "stack" class of template type is not inheriting into derived class "specialStack" of template type in C++?为什么这个来自模板类型“stack”类的 isEmpty() 没有继承到 C++ 中模板类型的派生类“specialStack”?
【发布时间】:2021-02-06 05:06:35
【问题描述】:

我有一个类模板“Stack”,用于制作堆栈数据结构。另一个类模板“specialStack”(公开继承“stack”类)用于在 O(1) 时间复杂度内从堆栈中获取最小元素 - getMin() 可以完成这项工作。

我从基类继承 isEmpty() 时出错。它显示 isEmpty() 未声明的标识符(如您在下面的屏幕截图中所见)。我发现要解决这个问题,我们必须再次覆盖派生类中的函数,但如果我们在基类中有很多函数,则不可能覆盖所有函数。我还尝试了第二种方法,通过在派生类中使用 stack::isEmpty() 来解决这个问题,但现在它又给了我一堆错误。

这是我的代码:-

#include<iostream>
using namespace std;
template<class T>
class stack {
    static const int max = 100;
    int arr[max];
    int top = -1, size = max;
public:
    void push(T x);
    T pop();
    int isEmpty();
    T topElement();
};
template<class T>
int stack<T>::isEmpty() {
    if (top == -1) return 1;
    return 0;
}
template<class T>
void stack<T>::push(T x) {
    if (top!=size) arr[++top] = x;
}
template<class T>
T stack<T>::pop() {
    if (top != -1)
    {
        return arr[top--];
    }
}
template<class T>
T stack<T>::topElement() {
    if (top != -1) return arr[top];
}
template<class T>
class specialStack : public stack<T> {
    stack<T>min;
public:
    void push(T x);
    T pop();
    T getMin();
};
template<class T>
void specialStack<T>::push(T x) {
    if (isEmpty()) {
        min.push(x);
        stack::push(x);
    }
    else {
        T y = min.topElement();
        if (x < y)
        {
            stack::push(x);
            min.push(x);
        }
        else {
            stack::push(x);
            min.push(y);
        }
    }
}
template<class T>
T specialStack<T>::pop() {
    if (true)
    {
        min.pop();
        stack::pop();
    }
}
template<class T>
T specialStack<T>::getMin() {
    return min.topElement();
}
int main() {
    specialStack<int>st;
    st.push(1);
    st.push(2);
    st.push(3);
    st.push(4);
    st.push(5);
    st.push(6);
    cout << st.getMin();
}

这是错误截图:

【问题讨论】:

标签: c++ c++11 inheritance class-template


【解决方案1】:

您也应该将模板参数T 传递给基类stack,因为它是一个模板类,然后使用stack&lt;T&gt;:: 范围运算符调用它的所有函数。

所以你会:

stack<T>::push(x);

stack<T>::isEmpty();

【讨论】:

    【解决方案2】:

    specialStack的定义中,stack&lt;T&gt;是一个dependent name;依赖于类型模板参数T of specialStack.

    解决此问题的常用方法是为特定的T 特化基类stack 定义实用程序类型别名:

    class specialStack : public stack<T> {
        // stack<T> is a dependent name here.
        using Base = stack<T>;  // note: this can be private, and use
                                // solely for implementation ease.
        // ...
    };
    

    之后,您可以通过实用程序别名调用依赖基类类型stack&lt;T&gt; 的成员函数

    Base::isEmpty();
    
    // ...
    
    Base::push(x); // ...  and so on.
    

    或者,您可以使用stack&lt;T&gt; 限定对基类成员函数的每个特定调用

    stack<T>::isEmpty();
    
    // ...
    
    stack<T>::push(x);  //...  and so on.
    

    【讨论】:

    • 非常感谢这个实用程序类型别名。我不知道...
    【解决方案3】:

    要在子类中使用父函数,您需要以这种方式指定函数的命名空间

    stack<T>::isEmpty()
    

    当你在子类中使用它时。

    所以代码结果如下:

    #include<iostream>
    using namespace std;
    template<class T>
    class stack {
        static const int max = 100;
        int arr[max];
        int top = -1, size = max;
    public:
        void push(T x);
        T pop();
        int isEmpty();
        T topElement();
    };
    template<class T>
    int stack<T>::isEmpty() {
        if (top == -1) return 1;
        return 0;
    }
    template<class T>
    void stack<T>::push(T x) {
        if (top!=size) arr[++top] = x;
    }
    template<class T>
    T stack<T>::pop() {
        if (top != -1)
        {
            return arr[top--];
        }
    }
    template<class T>
    T stack<T>::topElement() {
        if (top != -1) return arr[top];
    }
    template<class T>
    class specialStack : public stack<T> {
        stack<T>min;
    public:
        void push(T x);
        T pop();
        T getMin();
    };
    template<class T>
    void specialStack<T>::push(T x) {
        if (stack<T>::isEmpty()) {
            min.push(x);
            stack<T>::push(x);
        }
        else {
            T y = min.topElement();
            if (x < y)
            {
                stack<T>::push(x);
                min.push(x);
            }
            else {
                stack<T>::push(x);
                min.push(y);
            }
        }
    }
    template<class T>
    T specialStack<T>::pop() {
        if (true)
        {
            min.pop();
            stack::pop();
        }
    }
    template<class T>
    T specialStack<T>::getMin() {
        return min.topElement();
    }
    int main() {
        specialStack<int>st;
        st.push(1);
        st.push(2);
        st.push(3);
        st.push(4);
        st.push(5);
        st.push(6);
        cout << st.getMin();
    
    }
    

    【讨论】:

    • 仅使用带有 isEmpty() 的命名空间会给出错误。我认为我们还必须将命名空间与“堆栈”的其他功能一起使用..
    • 是的...我没有注意到我专注于 isEmpty
    猜你喜欢
    • 2022-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-27
    • 2011-03-17
    • 1970-01-01
    相关资源
    最近更新 更多