C ++ Доступ к закрытому члену вложенного класса

Название может быть немного вводящим в заблуждение. У меня следующая проблема: у меня есть дерево, состоящее из листьев и внутренних узлов. Пользователь должен иметь возможность хранить любую информацию в листьях а также В дереве есть несколько методов, которые получают набор пользовательских значений и нуждаются в доступе к соответствующим листам в постоянное время (не амортизируется).

Мне пришла в голову следующая идея, но она не работает, потому что, к сожалению, я не могу получить доступ к закрытым членам вложенного класса: пользователь создает дерево а также также для каждого листа экземпляр UserElement который содержит значение user_defined для соответствующего листа. После вызова метода, подобного doSomethingWithTheTree (list>), и построения дерева, дерево создает соответствующие листья и сохраняет его в закрытом поле. leaf, Всякий раз, когда пользователь хочет вызвать метод с некоторыми листьями, соответствующими его значениям user_defined, он или она просто должен вызвать метод, передав соответствующий 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
}
}

3

Решение

Технически это вложенный класс (объявлено в другом классе), а не подкласс (который наследует от своего суперкласса).

Вы можете позволить классу 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>>);
// ...
};
};
8

Другие решения

Вы можете сделать

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

или же

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

Вы можете объявить class Tree friend в UserElement<>, что позволило бы Tree чтобы получить доступ все Члены UserElement<>,

0