C ++ - Struct需要访问类的私有实例变量

时间:2016-08-22 08:37:00

标签: c++ syntax organization

我的C ++有点生疏,所以我想知道你是否可以帮助我。基本上,我有两个结构和一个类,结构需要访问类的私有实例变量。

#ifndef TREE_H
#define TREE_H

#include <iostream>

struct Node {
    ...
    inline void addEdge(Edge* e);
};

inline void Node::addEdge(Edge* e) {
    char ch = inp[e->startIndex];
    edges[ch] = e;
}

struct Edge {
    Node* next = new Node();
    int startIndex = 0;
    friend std::ostream& operator<<(std::ostream& out, Edge e) {
        int index = inp.size() - e.startIndex + endIndex + 1;   // Here the edge needs access to the private members of the Tree class such as string inp, and int endIndex
        // ... do things with index
        return out;
    }
};


class Tree {
public:
    Tree();
    friend std::ostream& operator<<(std::ostream& out, Tree s);

private:
    Node* root = nullptr;
    int endIndex = 0;
    std::string inp;
    void foo();
    std::ostream& printTree(std::ostream& out, Node* curr, std::string append="");

};
#endif // TREE_H

显然上面的代码不起作用。我以为我会在课堂上移动结构。但随后&lt;&lt; edge for operator给我“无效使用非静态数据成员'endIndex'”错误。我确信可以使用的一个想法是在创建Edge时将endIndex的引用/指针作为Edge的成员传递,但我想知道什么是更好的方法。

2 个答案:

答案 0 :(得分:1)

我建议使用访客模式。

这是一个简短而不完整的例子,可以给你一个想法:

class Tree
{
    Node _Node;
    std::list<Node> _Children;
public:
    ... // other stuff, like AddChild(), etc.

    void Traverse(Visitor visitor)
    {
        visitor.HandleNodeData(_Node.Data);
        traverseChildren(visitor);
    }
};

我还会考虑将Tree类实现为模板。

答案 1 :(得分:0)

对于任何人未来的参考,我现在都使用指针解决方案;似乎完成了工作。我唯一的疑问是,Tree类中的endIndex是否必须在堆栈中(我认为它确实如此)。任何人都可以澄清吗?

#ifndef TREE_H
#define TREE_H

#include <iostream>

struct Node {
    ...
    inline void addEdge(Edge* e);
};

inline void Node::addEdge(Edge* e) {
    char ch = inp[e->startIndex];
    edges[ch] = e;
}

struct Edge {
    Edge(int start, int* endIndex) {        
        this->startIndex = start;
        this->endIndex = endIndex;
    }
    Node* next = new Node();
    int startIndex = 0;
    int* endIndex;
    friend std::ostream& operator<<(std::ostream& out, Edge e) {
        std::string value = inp.substr(e.startIndex,  *e.endIndex - e.startIndex + 1);
        out << "(---- " << value << "[" << e.startIndex << ", " << *e.endIndex << "] ---->)";
        return out;
    }
};


class Tree {
public:
    Tree();
    friend std::ostream& operator<<(std::ostream& out, Tree s);

private:
    Node* root = nullptr;
    int* endIndex = new int;   // am i correct in saying this needs to be on the stack? 
    std::string inp;
    void foo();
    std::ostream& printTree(std::ostream& out, Node* curr, std::string append="");

};
#endif // TREE_H