Struct vs Class
Parte da seção Programação Orientada a Objetos do Journey de C++ da Coddy — lição 37 de 104.
Em C++, struct e class são quase idênticos. Ambos podem ter variáveis de membro, funções de membro, construtores e suportar herança. A única diferença é o seu nível de acesso padrão.
Em uma class, os membros são privados por padrão. Em uma struct, os membros são públicos por padrão:
struct Point {
int x; // público por padrão
int y; // público por padrão
};
class Circle {
double radius; // privado por padrão
public:
double getRadius() { return radius; }
};Isso também se aplica à herança. Uma struct herda publicamente por padrão, enquanto uma class herda privadamente:
struct DerivedStruct : Base {}; // herança pública
class DerivedClass : Base {}; // herança privadaAlém desses padrões, não há diferença técnica. No entanto, a convenção importa.
A maioria dos programadores C++ usa struct para contêineres de dados simples com membros públicos (como uma coordenada ou configuração), e class quando o encapsulamento e o comportamento são importantes. Seguir essa convenção torna a intenção do seu código mais clara para outros desenvolvedores.
Desafio
FácilVamos construir um sistema de configuração simples que demonstra quando usar struct versus class com base nas convenções de C++. Você criará uma struct para dados simples que devem ser acessíveis abertamente e uma class para dados que precisam de encapsulamento e acesso controlado.
Você criará dois arquivos para organizar seu código:
Config.h: Defina tanto uma struct quanto uma classe que representam diferentes tipos de dados de configuração.Primeiro, crie uma
structchamadaDimensions— um contêiner de dados simples para largura e altura (ambosint). Como as structs têm membros públicos por padrão, estes devem ser acessíveis diretamente sem getters. Inclua um métodoarea()que retorna o produto da largura e altura.Em seguida, crie uma
classchamadaAppConfigque gerencia as configurações do aplicativo com o encapsulamento adequado. Ela deve armazenar um nome de aplicativo (string) e um objetoDimensionspara o tamanho da janela. Como os membros da classe são privados por padrão, você precisará tornar explicitamente sua interface pública acessível. Forneça:- Um construtor que recebe o nome do aplicativo, largura e altura
- Um getter
getAppName()que retorna o nome - Um getter
getWindowSize()que retorna asDimensions - Um método
displayConfig()que imprime:"App: <name>, Window: <width>x<height>, Area: <area>"
main.cpp: Demonstre a diferença entre o uso de struct e class. Leia um nome de aplicativo, largura e altura da entrada (três linhas separadas) e, em seguida:- Crie uma struct
Dimensionsdiretamente com os valores de largura e altura — acesse seus membros diretamente para imprimir:"Direct struct access: <width> x <height>" - Crie um objeto
AppConfigcom todos os três valores - Chame
displayConfig()para mostrar a configuração completa - Use o getter para recuperar as dimensões da janela e imprima:
"Via getter - Area: <area>"
- Crie uma struct
Este desafio destaca a convenção: use struct quando tiver dados simples e transparentes (como coordenadas ou dimensões) e use class quando quiser controlar o acesso e adicionar comportamento em torno de seus dados.
Converta as entradas de largura e altura de strings para inteiros usando std::stoi(). Não se esqueça dos header guards em seu arquivo de cabeçalho.
Folha de consulta
Em C++, struct e class são quase idênticos, com uma diferença fundamental: seu nível de acesso padrão.
Em uma struct, os membros são públicos por padrão:
struct Point {
int x; // público por padrão
int y; // público por padrão
};Em uma class, os membros são privados por padrão:
class Circle {
double radius; // privado por padrão
public:
double getRadius() { return radius; }
};Isso também se aplica à herança:
struct DerivedStruct : Base {}; // herança pública por padrão
class DerivedClass : Base {}; // herança privada por padrãoConvenção: Use struct para contêineres de dados simples com membros públicos, e class quando o encapsulamento e o comportamento forem importantes.
Experimente você mesmo
#include <iostream>
#include <string>
#include "Config.h"
using namespace std;
int main() {
// Ler entrada
string appName;
string widthStr;
string heightStr;
getline(cin, appName);
getline(cin, widthStr);
getline(cin, heightStr);
int width = stoi(widthStr);
int height = stoi(heightStr);
// TODO: Criar uma struct Dimensions com width e height
// Acessar seus membros diretamente para imprimir: "Direct struct access: <width> x <height>"
// TODO: Criar um objeto AppConfig com appName, width e height
// TODO: Chamar displayConfig() no objeto AppConfig
// TODO: Usar o getter getWindowSize() para obter as dimensões e imprimir: "Via getter - Area: <area>"
return 0;
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de OOP
Arquivos ExternosBuild e Compilação em C++Arquivos Header e SourceNamespaces e EscopoIntrodução a OOP em C++Classes vs ObjetosO Ponteiro 'this'Métodos (Funções Membro)Atributos (Membros de Dados)Básico de Ctors e DtorsRecapitulação - Calculadora Simples4Propriedades de Classe
Membros de Instância vs EstáticosGetters e SettersFunções de Membro ConstPalavra-chave MutableMétodos e Variáveis EstáticosFunções e Classes FriendRecapitulação - Gerenciador de Conta Bancária7Herança
Herança BásicaNíveis de Acesso na HerançaOrdem de Chamada de Ctor e DtorSobrescrita de MétodosFunções Virtuais e VTableHerança MúltiplaHerança VirtualRecapitulação - Hierarquia de Funcionários2Gerenciamento de Memória
Memória Stack vs HeapPonteiros e ReferênciasMemória Dinâmica (new/delete)Smart Pointers em C++RAII em C++Recapitulação - Gerenciador de Array Dinâmico5Encapsulamento
Especificadores de Acesso em C++Especificadores de Acesso em DetalhesOcultação de InformaçãoStruct vs ClassClasses Aninhadas e InternasRecapitulação - Sistema de Registros de Alunos8Polimorfismo
Polimorfismo de Compilação vs Tempo de ExecuçãoSobrecarga de FunçõesFunções Virtuais RevisitadasFunções Virtuais PurasClasses AbstratasDesign de Interfaces em C++Dynamic Casting e RTTIRecapitulação - Calculadora de Formas3Construtores e Destrutores
Construtor PadrãoConstrutor ParametrizadoConstrutor de CópiaConstrutor de MovimentaçãoListas de Inicialização do ConstrutorConstrutores DelegadosMergulho Profundo em DestrutoresRegra dos Três / Cinco / ZeroRecapitulação - Classe String6Sobrecarga de Operadores
Introdução à Sobrecarga de OperadoresSobrecarga de Operadores AritméticosSobrecarga de Operadores de ComparaçãoOperadores de StreamSobrecarga do Operador de AtribuiçãoSobrecarga dos Operadores [] e ()Operadores de Conversão de TipoRecapitulação - Classe Matrix9Templates
Templates de FunçãoTemplates de ClasseEspecialização de TemplatesTemplates VariádicosFundamentos de SFINAE e Type TraitsRecapitulação - Container Genérico