Может ли класс внутри класса вызвать метод получения из внешнего класса?

У меня есть класс внутри класса.

Внешний класс выполняет некоторую обработку для создания массива значений.

Я хочу, чтобы внутренний класс имел доступ к массиву внешнего класса.

Есть ли чистый способ добиться этого?

Я думаю иметь метод во внешнем классе, который вызывает метод во внутреннем классе, отправляя ему адрес массива, а внутренний класс должен содержать указатель в своем частном разделе члена, чтобы позже указать на него путем назначения из метода, который получает адрес. Но это кажется немного неуклюжим.

это помогает? reddit.com/r/cpp_questions/comments/btf6m1/…

Piyush Singh 29.05.2019 12:51

Пример может помочь.

L. F. 29.05.2019 12:57
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
596
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

При построении вы можете передать ссылку на внешний класс конструктору внутреннего класса. Используя ссылку, вы можете вызвать любую функцию внешнего класса.


// 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} или что-то в этом роде? Кроме того, если я просто хочу получить доступ к массиву, мне не нужна функция получения, есть ли еще более простой способ?

aName 29.05.2019 13:02

Красиво, но inner не внутри outer. Вы можете легко добиться этого: 1) переместите предварительное объявление внутрь outer. 2) определить внутренний как class outer::inner.

spectras 29.05.2019 13:04

@aName проверяет конструктор, this передается там внутреннему классу (вы также можете сделать это непосредственно при объявлении, как вы сказали)

local-ninja 29.05.2019 13:06

Вам нужно предварительно объявить outer, затем определить inner, затем определить outer. В этом порядке вы получаете ошибку неполного типа.

Weak to Enuma Elish 29.05.2019 13:08

@aName Вы можете получить доступ к массиву в экземпляре outer напрямую через _outer изнутри inner без необходимости создания геттера.

Weak to Enuma Elish 29.05.2019 13:10

Вы должны избегайте префикса идентификаторов с подчеркиванием _, вместо этого используйте подчеркивание в качестве суффикса (то естьinner_). В данном случае это законно, но лучше просто не делать этого.

Paul Evans 29.05.2019 13:17

Да, я удалил предварительное объявление и переместил определение класса. Вы можете делать предварительные объявления только со ссылками и указателями. @Paul хорошее замечание по поводу _.

Bart 29.05.2019 13:47

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

aName 29.05.2019 13:27

Как уже упоминалось, охватывающий класс (внешний) не может получить доступ к члену вложенного класса, поэтому, я думаю, вы не можете получить доступ к Fun в функции внешнего. Обновил код. Я сам никогда не пробовал с вложенным классом. Но надеюсь, что это сработает для вас

Piyush 29.05.2019 13:52

Хорошо, вот полностью. Ключевые моменты:

  • С++ имеет вложенные классы, однако это 100% времени компиляции, связанное с областью действия и инкапсуляцией, экземпляры класса на 100% независимы.
  • Поэтому, если вы хотите, чтобы какой-либо класс каким-либо образом использовал другой, он должен либо создать экземпляр, либо принять его.
  • (и затем, учитывая внешний экземпляр, внутреннему классу разрешен доступ к его закрытым частям, и это единственное, что на самом деле отличается от обычной области видимости).

Итак, зная это, вот конкретный пример.
→ Внешнему принадлежит вектор Внутренних.
→ Внутренний должен использовать свой внешний экземпляр
➥ скажем, Внешний может быть каким-то списком, а внутренний каким-то элементом

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
};

Примечания:

  • Любые отношения Outer и Inner зависят от вашего дизайна, C++ не предполагает их наличия.
  • Если Outer работает в тесной взаимосвязи с Inner, довольно часто Outer создает экземпляры Inner и передает им себя, как я сделал в addInner здесь.
  • Я сделал m_outer ссылку, но это не позволяет Inner удовлетворить *Назначаемые требования. Если вам нужен класс для их удовлетворения, вместо этого сделайте его указателем.

Спасибо за уделенное время. Удивительно, как такой маленький код может так сильно сбить с толку!

aName 30.05.2019 08:29

Другие вопросы по теме