У меня есть класс внутри класса.
Внешний класс выполняет некоторую обработку для создания массива значений.
Я хочу, чтобы внутренний класс имел доступ к массиву внешнего класса.
Есть ли чистый способ добиться этого?
Я думаю иметь метод во внешнем классе, который вызывает метод во внутреннем классе, отправляя ему адрес массива, а внутренний класс должен содержать указатель в своем частном разделе члена, чтобы позже указать на него путем назначения из метода, который получает адрес. Но это кажется немного неуклюжим.
Пример может помочь.
При построении вы можете передать ссылку на внешний класс конструктору внутреннего класса. Используя ссылку, вы можете вызвать любую функцию внешнего класса.
// The actual definition of the inner class.
class inner {
public:
inner(outer& o) : outer_(o) // Set the reference.
{
}
// The function using the data in outer.
void do_stuff()
{
int x = outer_.get_data() + 5;
}
private:
// A reference to the outer class.
outer& outer_;
}
// The actual outer class.
class outer {
public:
outer() : inner_(*this) // Set the reference using the this object.
{
}
// This is the function you would like to call.
int get_data();
private:
inner inner_;
}
Привет, Барт, где внешняя ссылка передает что-либо в конструктор внутреннего класса? Разве внутренний не нужно объявлять так Inner inner{this}
или что-то в этом роде? Кроме того, если я просто хочу получить доступ к массиву, мне не нужна функция получения, есть ли еще более простой способ?
Красиво, но inner
не внутри outer
. Вы можете легко добиться этого: 1) переместите предварительное объявление внутрь outer
. 2) определить внутренний как class outer::inner
.
@aName проверяет конструктор, this
передается там внутреннему классу (вы также можете сделать это непосредственно при объявлении, как вы сказали)
Вам нужно предварительно объявить outer
, затем определить inner
, затем определить outer
. В этом порядке вы получаете ошибку неполного типа.
@aName Вы можете получить доступ к массиву в экземпляре outer
напрямую через _outer
изнутри inner
без необходимости создания геттера.
Вы должны избегайте префикса идентификаторов с подчеркиванием _
, вместо этого используйте подчеркивание в качестве суффикса (то естьinner_
). В данном случае это законно, но лучше просто не делать этого.
Да, я удалил предварительное объявление и переместил определение класса. Вы можете делать предварительные объявления только со ссылками и указателями. @Paul хорошее замечание по поводу _.
C++ имеет концепцию вложенного класса. Вложенный класс, объявленный в другом охватывающем классе. Он является членом и имеет те же права доступа, что и любой другой член окружающего класса. Но члены окружающего класса не имеют специального доступа к членам вложенного класса. Вы можете обратиться к этому примеру кода. Надеюсь, это поможет
class Outer {
private:
int arry[];
class inner {
private:
int innerArr[];
void Fun(Outer *e) {
innerArr = e->arry;
}
};
};
int main(){
Outer out;
Outer::inner in;
in.Fun(out);
}
Это выглядит намного чище / проще (и в основном это то, что у меня есть сейчас), но как передать адрес Внешнего для развлечения. Я сделал это, имея внешнюю функцию, которая будет вызывать Fun
Как уже упоминалось, охватывающий класс (внешний) не может получить доступ к члену вложенного класса, поэтому, я думаю, вы не можете получить доступ к Fun в функции внешнего. Обновил код. Я сам никогда не пробовал с вложенным классом. Но надеюсь, что это сработает для вас
Хорошо, вот полностью. Ключевые моменты:
Итак, зная это, вот конкретный пример.
→ Внешнему принадлежит вектор Внутренних.
→ Внутренний должен использовать свой внешний экземпляр
➥ скажем, Внешний может быть каким-то списком, а внутренний каким-то элементом
class Outer
{
public: // can be private, in which case Inner won't be usable from outside
class Inner
{
Outer & m_outer;
public:
Inner(Outer & outer) : m_outer(outer) {}
void doOuterMagic() { m_outer.doMagic(); }
};
public:
void addInner() { m_inners.emplace_back(*this); }
private: // could be public, but I want to illustrate Inner access to private members
void doMagic() { std::cout <<"magic"; }
private:
std::vector<Inner> m_inners;
};
Как и в случае с любым классом, вы также можете определить его ниже внешнего класса, если он более удобочитаем. Вы бы сделали это так:
class Outer
{
public: // can be private, in which case Inner won't be usable from outside
class Inner;
public:
// ... unchanged ...
};
class Outer::Inner // note the scoping here
{
// ... exactly what was in class Inner above
};
Примечания:
addInner
здесь.m_outer
ссылку, но это не позволяет Inner
удовлетворить *Назначаемые требования. Если вам нужен класс для их удовлетворения, вместо этого сделайте его указателем.Спасибо за уделенное время. Удивительно, как такой маленький код может так сильно сбить с толку!
это помогает? reddit.com/r/cpp_questions/comments/btf6m1/…