Я бы сказал, по крайней мере, в 90% случаев, когда возникают подобные вопросы, это хороший признак того, что вы, вероятно, пытаетесь использовать слишком много функциональности в одном классе. Если к someStruct::SuperInternalValue
действительно нужно получить доступ через getSuperInternalValue
, то вполне вероятно, что он должен быть частью someStruct
, а не частью Object
.
Аналогично, если вам нужно распечатать someStruct
, тогда Object должен просто использовать функцию-член (или перегруженный оператор на языке, который его поддерживает), чтобы распечатать объект someStruct
(в целом). Как вы уже написали, Object::printThatSuperInternalValue
знает все о someStruct
и superInternalValue
.
Несмотря на исходный код, содержащий «класс» и «объект», у вас действительно есть код в Object
, действующий на немых данных в someStruct
. Другими словами, то, что у вас есть, на самом деле вовсе не ОО - это простой процедурный код со структурой данных. Это не обязательно все плохо, но, основываясь на теге encapsulation
, я думаю, это справедливое предположение, что это, вероятно, не то, что вы действительно хотите.
class Object {
int internalValue;
public:
class someStruct {
int superInternalValue;
public:
someStruct(int v) : superInternalValue(v) {}
someStruct &operator=(someStruct const &n) {
superInternalValue = n.superInternalValue;
return *this;
}
friend ostream &operator<<(ostream &os, someStruct const &s) {
return os << s.superInternalValue;
}
};
friend ostream &operator<<(ostream &os, Object const &o) {
return os << internalValue;
}
};
Таким образом, мы определили someStruct
в терминах интерфейса (мы можем создать его из int, назначить их и напечатать их), и Object вообще не нужно иметь дело с / touch superInternalValue
. Важно не то, что мы остановили Object
от игры с внутренностями somestruct
, но мы сделали someStruct
достаточно умным, чтобы Object
теперь мог игнорировать все кровавые подробности того, как someStruct
реализовано.