继承 c++ 的参数太少

Too few arguments inheritance c++

本文关键字:参数 c++ 继承      更新时间:2023-10-16

我正在通过制作一个通用List类来学习继承。 List可以是Unordered列表、Ordered列表、StackQueue

我的List类如下所示:

class List
{
public:
    class Node
    {
    public:
        int data;
        Node * next;
        Node(int data);
    };
    int sizeOfList = 0;
    Node * head = nullptr;
    List::List();
    virtual void get(int pos);
    virtual void insert(int data);
    virtual void remove(int pos);
    virtual void list();
    virtual int size();
};

我的Unordered列表类如下所示:

class UnOrderedList : public List
{
public:
    UnOrderedList();
    void get();
    void insert(int data);
    virtual void remove(); //takes no parameters because first item is always removed
};

main()中,我创建了一个这样的列表数组;

List * lists[8];

并像这样制作一个无序列表:

lists[0] = new UnOrderedList();

我的问题: lists[listNum]->get();给出错误

"函数调用中的参数太少"

因为它认为我正在尝试在List类中调用get(),但我希望它调用无序列表的函数get()

我觉得我必须改进Sam Varshachik的回答 - 尽管他是完全正确的。

class List
{
public:
    virtual void get(int pos);
};
class UnOrderedList : public List
{
public:
    void get();
};

请注意,这里有两个问题 - 不仅仅是一个。

首先,get(int) 的签名与 get() 不同 - 这是两种不同的方法,编译器会这样处理它们.
此外,您已经声明该方法List::get(int)虚拟的,但您没有这样做 - 对于UnOrderedList::get() - 请记住,list对象不知道它的子对象 - 因此list *无法理解UnOrderedList的细节。

请考虑以下示例:

class List
{
public:
    virtual void get(int pos);
};
class UnOrderedList : public List
{
public:
    virtual void get(); //STILL AN ERROR!
};

在这种情况下,我已经UnOrderedList::get()虚拟的 - 但这无济于事。由于列表仍然不知道这种方法

正确的代码段如下所示:

class List
{
public:
    virtual void get(int pos);
    virtual void get();
};
class UnOrderedList : public List
{
public:
    virtual void get(); //We can use this now!
    virtual void get(int pos); //This is only needed if we intend to override this method
};

在此示例中,list::get()现在是一个虚拟方法 - 因此,对它的任何调用都将按照您的预期传达给正确的子项.
但是,这只能是可能的,因为父类已被告知存在此类方法,并且可以被子类重写

[编辑/]

正如 JonathanPotter 在评论中所说,请注意,仅当您希望将从父指针调用的方法路由到实际的子对象时,才需要 virtual 关键字。这确实会产生一些开销。

您需要将get()声明为List类中的虚拟方法。 要么这样,要么dynamic_cast它。

当你使用指向List的指针调用get()时,该特定指针可以指向List的任何子类。仅仅因为 List 的一个特定子类实现了特定方法并不意味着您可以使用指向基类的指针直接调用它。

否则,没有必要使用基类。这正是虚拟方法的用途:允许您使用指向基类的指针调用子类中的方法。

lists[0]

编译器而言是一个List*

UnOrderedList::get()不会覆盖List::get(int pos),因为签名不同。如果希望派生类重写基类中的函数,则函数签名必须相同。

实际上,您需要将lists[listNum]转换为UnOrderedList*才能调用UnOrderedList::get(),例如 static_cast<UnOrderedList*>(lists[listNum])->get() .