Classes aninhadas em C++

Jinku Hu 12 outubro 2023
Classes aninhadas em C++

Este artigo explicará como classes e estruturas aninhadas funcionam em C++.

Defina um objeto class ou struct dentro de outra classe em C++

Às vezes, nossas classes precisam dos chamados tipos de dados auxiliares, geralmente definidos como objetos struct ou class personalizados. Essas classes auxiliares podem ser definidas dentro de outras classes e, em tais casos, serão chamadas de tipos aninhados ou classes aninhadas. O último conceito oferece muitas vantagens para o programador, como bons limites de escopo e controle de acesso.

O exemplo a seguir é mostrado para demonstrar um cenário simples onde podemos definir uma classe aninhada. A classe principal - CircularList implementa uma lista ligada circular e precisa definir um nó que é um tipo composto, denominado - ListNode. Neste caso, o último é definido no escopo global usando a palavra-chave struct. Assim, seus membros são acessíveis publicamente por outras classes.

#include <iostream>
#include <string>

using std::string;

struct ListNode {
  struct ListNode *next = nullptr;
  string data;
} typedef ListNode;

class CircularList {
 public:
  explicit CircularList(string data) {
    head = new ListNode;
    head->next = head;
    head->data = std::move(data);
    end = head;
  };

  ListNode *insertNodeEnd(string data);
  ListNode *insertNodeHead(string data);
  void printNodes();

  ~CircularList();

 private:
  ListNode *head = nullptr;
  ListNode *end = nullptr;
};

int main() { return EXIT_SUCCESS; }

Alternativamente, podemos mover a definição ListNode para a classe CircularList. ListNode não está acessível no namespace global, portanto, precisamos incluir o namespace CircularList antes dos nomes das classes aninhadas. Além disso, é importante qual especificador de acesso a classe aninhada possui, já que as regras de controle de acesso usuais também se aplicam a eles.

Neste caso, ListNode é definido como uma classe de membro público e, conseqüentemente, pode ser acessado a partir da função main usando a notação CircularList::ListNode. Se uma classe aninhada é definida como um membro protegido, ela é acessível pela classe envolvente, pelas classes amigas da última e pelas classes derivadas. Por outro lado, um especificador private para uma classe aninhada significaria que ela só está acessível dentro da classe envolvente e das classes amigas.

#include <iostream>
#include <string>

using std::string;

class CircularList {
 public:
  // Helper Types ->
  struct ListNode {
    struct ListNode *next = nullptr;
    string data;
  } typedef ListNode;

  // Member Functions ->
  explicit CircularList(string data) {
    head = new ListNode;
    head->next = head;
    head->data = std::move(data);
    end = head;
  };

  ListNode *insertNodeEnd(string data);
  ListNode *insertNodeHead(string data);
  void printNodes();

  ~CircularList();

 private:
  ListNode *head = nullptr;
  ListNode *end = nullptr;
};

int main() {
  //    ListNode *n1; // Error
  CircularList::ListNode *n2;

  return EXIT_SUCCESS;
}

Geralmente, uma classe aninhada pode ter especificadores de acesso usuais para seus membros, e as regras se aplicarão à classe envolvente como regulares. Enquanto isso, uma classe aninhada não recebe nenhum acesso especial aos membros da classe envolvente.

Autor: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Artigo relacionado - C++ Class