C++访问嵌套类的私有成员

9
标题可能有点误导。 我有以下问题:我有一个由叶子和内部节点组成的树。用户应该能够在叶子节点中存储任何信息,并且树具有一些方法,这些方法会获取一组用户定义的值,并需要在常数时间(而不是摊销时间)内访问相应的叶子节点。
我想到了以下的解决方案,但由于无法访问嵌套类的私有成员,因此它不起作用:用户创建树,并为每个叶子节点创建一个UserElement实例,其中包含相应叶子节点的用户定义值。一旦调用像doSomethingWithTheTree(list>)这样的方法并且构建了树,则树将创建相应的叶子节点并将其保存在私有字段leaf中。每当用户想要调用一些与其用户定义值对应的叶子节点的方法时,只需通过提供相应的UserElement调用该方法,然后树可以在常数时间内检索相应的叶子节点。
class Tree {
    public:
        template <typename T>
        class UserElement {
            private:
                T user_value;
                tree_node* leaf; // this has to be private for
                                 // everyone outside the class `Tree`
            public:
                T getInf() {
                    return user_value;
                }
                void setInf(T i) {
                    user_value = i;
                }
        };

        void doSomethingWithTheTree(list<UserElement<T>> elements) {
            ...
            // I want to be able to access elem.leaf for all elements
        }
}

1
那是一个嵌套类,而不是子类。小心术语的使用,问题的意思会发生很大变化。 - Manu343726
3个回答

15

从技术上讲,那是一个嵌套类(在另一个类中声明的类),而不是一个子类(继承自其超类)。

您可以通过将其设置为友元来允许 Tree 类访问其私有成员:

class UserElement {
    friend class Tree;
    // ...
};

或者,为了更好的封装,您可以仅将访问权限限制在需要它的成员函数上,虽然由于需要按正确顺序声明事物而变得有些混乱:

或者,为了更好的封装,您可以仅将访问权限限制在需要它的成员函数上,虽然由于需要按正确顺序声明事物而变得有些混乱:

class Tree {
public:
    // Declare this so we can declare the function
    template <typename T> class UserElement;

    // Declare this before defining `UserElement` so we can use it
    // in the friend declaration
    template <typename T>
    void doSomethingWithTheTree(list<UserElement<T>> elements) {
        elements.front().leaf;
    }

    template <typename T>
    class UserElement {
        // Finally, we can declare it a friend.
        friend void Tree::doSomethingWithTheTree<T>(list<UserElement<T>>);
        // ...
    };
};

1

你可以这样做

class Outer {
   private: // maybe protected:
   class Inner {
      public:
      ....
   };
};

或者

class Outer {
   public:
   class Inner {
      friend class Outer;
      private:
      ....
   };
};

1
谢谢您的快速回答。第一种解决方案对我不起作用,因为Inner必须从Outer外部调用。但第二种解决方案很好用。我不知道C++有类似于friend的东西 :) - user1305497

0
您可以将 class Tree 声明为 UserElement<>friend,这允许 Tree 访问 UserElement<>所有成员。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接