c++ - 当基类想要访问继承类的成员时

标签 c++ class inheritance nodes edges

这是我的情况:

我正在用 C++ 编写一个由节点和边组成的数据结构。 节点通过边连接到其他节点。

我有不同类型的节点,例如文本节点或整数节点。 文本节点与文本节点相连,整数节点与整数节点相连。 我使用继承来实现不同类型的节点,因为它很有意义: 从根本上讲,所有节点都连接到其他节点,因此 Node 是基类, TxtNode、IntNode 是继承类,它们共享节点的基本属性。

但是,当我尝试从继承节点获取连接的继承节点时,这会给我带来问题,因为获取函数(检索连接到调用节点的特定节点的函数)是在基类 Node 中定义的。例如,从 TextNode 调用此获取函数会返回 TextNode 的基本版本,它缺少额外的信息。

我不确定在这里应该做什么明智的编码实践。 我选择这种方式编码是因为我必须为所有不同类型的节点定义不同的连接获取函数似乎没有意义。

如果我可以透露更多信息,请告诉我。

这是我的代码,我正在尝试打印继承节点的伙伴,但这将导致打印基本节点。

节点.cpp

#include "Node.h"
#include "Edge.h"

#include "common.h"

#include <vector>
#include <cassert>
#include <cstddef>
#include <stdint.h>
#include <iostream>

Node::Node() {
    id = (intptr_t)this;
    edges.clear();
}

int Node::connect(Node* dst) {
    // establish link between calling node
    // and dst node, first linkage will
    // edge between each other, links after
    // increments strength. returns number of
    // links

    // fetch edge connecting this node and 
    // dst node
    Edge* edge = findDstEdge(dst);

    // if the branch isn't established yet,
    // then make connection
    if (edge==NULL) {
        establishConnection(dst, 1);
        return 0;
    } else {
        edge->strengthenConnection();
        return 1;
    }

}

Edge* Node::findDstEdge(Node* dst) {
    // fetches edge corresponding
    // to destination node

    // walk through vector of edges to find
    // edge connecting to dst

    vector<Edge*>::iterator iter = edges.begin();

while(iter!=edges.end()) {
    Edge* e = *iter;
    Node* partner = e->getPartner(this);
    if (partner->getID() == dst->getID())
        return e;
    iter++;
    }
    // not found
    return NULL;
}

void Node::establishConnection(Node* dst, int str) {
    // low level node addition

    // establish a new edge between
    // nodes which don't know each other
    Edge* e = new Edge(this, dst, str);
    this->manuallyConnect(e);
    dst->manuallyConnect(e);
}

void Node::manuallyConnect(Edge* e) {
    edges.push_back(e);
}

ostream& operator<<(ostream& stream,Node n) {

    vector<Edge*>::iterator iter = n.edges.begin();

    while(iter!=n.edges.end()) {
        Edge* e = *iter;
        stream << *e << endl;
        iter++;
    }

    return stream;
}

节点.h

#ifndef _NODE_H_
#define _NODE_H_

#include "common.h"

#include <vector>
#include <string>
#include <stdint.h>

class Edge;

using namespace std;

class Node {  

  protected:
    vector<Edge*> edges;
    intptr_t id;

  public:
    Node();

    // manipulation
    void establishConnection(Node* dst,
           int str);
    int connect(Node* dst);
    Edge* findDstEdge(Node* dst);

    // fetchers
    intptr_t getID() {return id;}
    vector<Edge*> getEdges() {return edges;}

    void manuallyConnect(Edge* e);

    friend ostream& operator<<(ostream& stream, Node n);
};

#endif

TxtNode.cpp

#include "TxtNode.h"
#include "Edge.h"

#include "common.h"

#include <iostream>

TxtNode::TxtNode(char c): Node()  {
    _c = c;
}

ostream& operator<<(ostream& stream, TxtNode tn) {
    // print out character of this TxtNode
    stream << "char: " << tn._c << endl;
    stream << "id: " << tn.id << endl;

    // print out all connections and its
    // strength
    vector<Edge*>::iterator iter = tn.edges.begin();

    while(iter!=tn.edges.end()) {
        Edge* e = *iter;
        stream << *e << endl;
        iter++;
    }

    return stream;
}

边缘.cpp

#include "Edge.h"
#include "Node.h"

#include "common.h"

#include <cassert>
#include <iostream>

using namespace std;

Edge::Edge(Node* a, Node* b, int str) {
    node_a = a;
    node_b = b;
    strength = str;
}

void Edge::strengthenConnection() {
    strength++;
}

Node* Edge::getPartner(Node* src) {
    uint src_ID = src->getID();
    if (node_a->getID() == src_ID)
        return node_b;
    else if (node_b->getID() == src_ID)
        return node_a;
    assert(false);
}

ostream& operator<<(ostream& stream, Edge e) {
    stream << "strength: "
           << e.strength
           << endl;
    stream << "node_a: "
           << e.node_a->getID()
           << endl;
    stream << "node_b: "
           << e.node_b->getID()
           << endl;
    return stream;
}

目前我只有打印 ID(intptr_t)的代码, 因为我发现我无法从基类访问继承类的成员。

我倾向于从基类访问继承类的成员,因为边缘类处理基节点类。

最佳答案

如果有类代码就好了。

根据您的说法,您没有将 fetch 函数声明为虚拟函数。

这是一个关于虚拟/非虚拟函数如何工作的非常简单的示例

class baseNode {
 public:
    int fetch() { printf "fetched from base";};
}

class intNode : public baseNode {
 public:
    int fetch() { printf "fetched from derived int";};
}

class txtNode : public baseNode {
 public:
    int fetch() { printf "fetched from derived txt";};
}

以下代码

baseNode * ptr = new intNode();
ptr->fetch();

将打印“从基地获取”

但是如果你将 fetch 函数声明为 virtual :

class baseNode {
 public:
     virtual int fetch() { printf " fetched from base";};
}

然后相同的代码将打印“从派生 int 获取”。

关于c++ - 当基类想要访问继承类的成员时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25213627/

相关文章:

c# - 这个不可变结构应该是一个可变类吗?

class - 为什么有 GLint 和 GLfloat?

Java - 将子类传递给类型为父类(super class)的构造函数

C# List<baseClass> - 有什么方法可以在其中存储继承的类吗?

c++ - 无法使用 std::unique_ptr 初始化指针

c++ - 如何在 MVS 中使用 OpenGL 绘制实时二维图形

c++ - 你能在没有列表或 vector 的情况下遍历类对象吗?

c++ -/usr/lib64/libstdc++.so.6 : version `GLIBCXX_3.4.15' not found

swift - xcode swift 3 锁屏 Remote 不工作?

c++ - 下面的类继承如何设计?