gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:43:23 26 4
gpt4 key购买 nike

这是我的情况:

我正在用 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

文本节点.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();

将打印“fetched from base”

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

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

然后相同的代码将打印“fetched from derived int”。

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

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com