如何访问不在基类中的派生类中的 STL 类的成员函数? (正文中的详细解释)

Posted

技术标签:

【中文标题】如何访问不在基类中的派生类中的 STL 类的成员函数? (正文中的详细解释)【英文标题】:How can I access member functions of STL classes inside derived classes that aren't in the base class? (detailed explanation in body) 【发布时间】:2019-10-16 03:42:03 【问题描述】:

现在我有一个基类,Base 类,它派生出两个类,BFS 和 DFS。 BFS 有队列,DFS 有堆栈,所以它们都有一个名为“nodes”的成员,但类型是它们各自的 std::queue 和 std::stack。我的搜索函数将一个指向基类的指针作为其参数,以便它可以接受两个派生类,并通过从派生类内部的成员类中推送和弹出来运行搜索(按照通常的 DFS BFS 算法)。问题是,由于我将基类作为参数传入,每当我尝试从派生类中调用名为“节点”的成员堆栈/队列上的推送或弹出时,它总是说无法完成推送/弹出,因为基类中没有称为“节点”的成员。我该怎么做? 此外,此设置是我正在做的任务的要求,我只是无法弄清楚这应该如何工作,感谢任何帮助。 谢谢!

class Base 
public:
    virtual void push(uint64_t roomID, float intensity, int distance) = 0;
    virtual Node pop(void) = 0;
    virtual int size(void) = 0;
;

class Breadth : public Base 
public:
    std::queue<std::pair<uint64_t, int>> U;
    void push(uint64_t roomID, float intensity, int distance)  std::pair<uint64_t, int> p(roomID, distance); U.push(p); 
    Node pop()  Node rr; rr.ID = U.front().first; rr.distance = U.front().second;  U.pop(); return rr; 
    int size()  return U.size(); 
;

class Depth : public Base 
public:
    std::stack<std::pair<uint64_t, int>> U;
    void push(uint64_t roomID, float intensity, int distance)  std::pair<uint64_t, int> p(roomID, distance); U.push(p); 
    UnexploredRoom pop()  U.pop(); 
    int size()  U.size(); 
;

void robotSearch::searchLoop(Base* search, Discovered* D, uint64_t roomID)

    Node room;
    room.ID = roomID;
    room.distance = 0;
    search->U.push(room); //problem here, compiler wont let me push U
    ...

【问题讨论】:

如果您将正在尝试做的事情链接到 MCVE,将会很有帮助。 【参考方案1】:

要通过指向基类的指针来实现自定义行为,您需要使用virtual functions。另一种方法是使用带有模板的通用代码。

例子:

class Base 
public:
    virtual ~Base() 
    virtual void push(int i) = 0;
    virtual int pop() = 0;
;

class DFS : public Base
public:
    virtual void push(int i) override  /*...*/ 
    virtual int pop() override  /*...*/ return ; 
;

class BFS : public Base 
public:
    virtual void push(int i) override  /*...*/ 
    virtual int pop() override  /*...*/ return ; 
;

【讨论】:

是的,我已经有了虚拟功能。一切都和你的一样,除了我的 BFS 和 DFS 类,每个都有一个额外的成员。对于 BFS,它是 std::queue 节点,对于 DFS,它是 std::stack 节点。但是,当我尝试使用基类指针推送到队列或堆栈时,它不起作用,我不知道如何让它推送到派生类的成员而不是基类。 在您提供MCVE 之前,我真的无法为您提供帮助。我坐下来写了一些代码并链接了它,至少你能做的也是一样的。 添加了 mcve,有点犹豫将硬件代码放到网上。 “节点”堆栈和队列在这里是 U【参考方案2】:

现在,您有一些虚拟方法pushpop,但出于某种原因,您没有使用它们,而是尝试访问派生类的成员。您似乎从 Ayjay 的答案中复制了代码,但没有正确应用它。 那个成员U真的不应该这样暴露,也就是应该是private,你应该用你的类方法来操作它。

所以你不会写

search->U.push(room);

即使它在此处 是合法的(它不是,因为基类没有任何类似名称的东西)。 相反,您选择

search->push(room);

请注意,我省略了这需要的其他参数,当然您还必须为您的 intensitydistance 参数提供值。

这样做将调用适当的方法,即Breadth::pushDepth::push,然后将访问相应类的相应成员。

顺便说一句,出于控制的原因,您应该像 Ayjay 一样使用 override 关键字,而且,您应该给成员一个比 U 更具描述性的名称。

【讨论】:

我现在明白了,谢谢! (其实我并没有从 Ayjay 那里复制代码,是我硬件上的原始代码,我无法工作)

以上是关于如何访问不在基类中的派生类中的 STL 类的成员函数? (正文中的详细解释)的主要内容,如果未能解决你的问题,请参考以下文章

C#:基类中的受保护方法;无法使用来自另一个类的派生类对象进行访问[重复]

访问派生类中的基类成员

C#基础语法

关于继承

子类继承基类的三种继承方式

如何使用 C++ 中的继承函数访问派生类中的局部变量