Struct vs Classe
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-membro, funções-membro, construtores e oferecer suporte à herança. A única diferença é o 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 classe herda privadamente:
struct DerivedStruct : Base {}; // herança pública
class DerivedClass : Base {}; // herança privadaAlém desses default, não há diferença técnica. No entanto, a convenção é importante.
A maioria dos programadores de C++ usa struct para contêineres simples de dados 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 mais clara a intenção do seu código para outros desenvolvedores.
Desafio
FácilVamos criar um sistema simples de configuração que demonstra quando usar struct em vez de class com base nas convenções de C++. Você criará uma struct para dados simples que devem ser acessíveis diretamente e uma class para dados que precisam de encapsulamento e acesso controlado.
Você criará dois arquivos para organizar seu código:
Config.h: defina uma struct e uma class que representem diferentes tipos de dados de configuração.Primeiro, crie uma
structchamadaDimensions: um contêiner de dados simples para largura e altura (ambasint). Como os membros de structs são públicos por padrão, eles devem ser acessíveis diretamente, sem getters. Inclua um métodoarea()que retorne o produto da largura pela altura.Em seguida, crie uma
classchamadaAppConfigque gerencie 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 de classes são privados por padrão, você precisará tornar explicitamente sua interface pública acessível. Forneça:- Um construtor que receba o nome do aplicativo, a largura e a altura
- Um getter
getAppName()que retorne o nome - Um getter
getWindowSize()que retorne oDimensions - Um método
displayConfig()que imprima:"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, a largura e a altura da entrada (três linhas separadas) e então:- Crie uma
Dimensionsstruct diretamente com os valores de largura e altura: acesse seus membros diretamente para imprimir:"Direct struct access: <width> x <height>" - Crie um objeto
AppConfigcom os três valores - Chame
displayConfig()para mostrar a configuração completa - Use o getter para obter as dimensões da janela e imprimir:
"Via getter - Area: <area>"
- Crie uma
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 aos seus dados.
Converta as entradas de largura e altura de strings para inteiros usando std::stoi(). Não se esqueça das guardas de cabeçalho no seu arquivo de cabeçalho.
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: Crie uma struct Dimensions com width e height
// Access its members directly to print: "Direct struct access: <width> x <height>"
// TODO: Crie um objeto AppConfig com appName, width e height
// TODO: Chame displayConfig() no objeto AppConfig
// TODO: Use getWindowSize() getter to get dimensions and print: "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 POO
Arquivos externosBuild e compilação em C++Arquivos de cabeçalho e arquivos-fonteNamespaces e escopoIntrodução à POO em C++Classes vs. objetosO ponteiro 'this'Métodos (funções membro)Atributos (membros de dados)Noções básicas de construtores e destruidoresRevisão - calculadora simples4Propriedades de Classe
Membros de Instância vs. EstáticosGetters e SettersFunções Membro ConstPalavra-chave MutableMétodos e Variáveis EstáticosFunções e Classes FriendRevisão - Gerenciador de Contas Bancárias7Herança
Herança básicaNíveis de acesso da herançaOrdem de chamada de construtor e destrutorSobrescrita de métodosFunções virtuais e VTableHerança múltiplaHerança virtualRevisão - Hierarquia de funcionários10Visão geral da STL
Visão geral e filosofia da STLContêineres da STLIteradoresAlgoritmos da STLFunctors e expressões lambdaRecapitulação - Frequência de palavras13Padrões de Projeto — Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonFactory e Abstract FactoryPadrão BuilderPadrão ObserverPadrão Strategy2Gerenciamento de Memória
Memória Stack vs. HeapPonteiros e ReferênciasMemória Dinâmica (new/delete)Ponteiros Inteligentes em C++RAII em C++Revisão - Gerenciador de Array Dinâmico5Encapsulamento
Especificadores de acesso em C++Especificadores de acesso em profundidadeOcultação de informaçõesStruct vs ClasseClasses aninhadas e internasRecapitulação - Sistema de registros de alunos8Polimorfismo
Polimorfismo em compilação vs. execuçãoSobrecarga de funçõesFunções virtuais revisadasFunções virtuais purasClasses abstratasDesign de interfaces em C++Conversão dinâmica e RTTIRecapitulação — Calculadora de formas11Conceitos Avançados de OOP
Composição vs. HerançaMixins via CRTPIdioma PimplApagamento de TiposClasses Enum e Tipagem ForteTratamento de Exceções em OOPHierarquias de Exceções Personalizadas14Padrões de Projeto — Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositeRAII como Padrão3Construtores e Destrutores
Construtor PadrãoConstrutor ParametrizadoConstrutor de CópiaConstrutor de MovimentoListas de Inicialização do ConstrutorConstrutores DelegantesAprofundamento em DestrutoresRegra dos Três / Cinco / ZeroRevisão - Classe String6Sobrecarga de Operadores
Introdução à Sobrecarga de OperadoresSobrecarga de Operadores AritméticosSobrecarga de Operadores de ComparaçãoOperadores de FluxoSobrecarga do Operador de AtribuiçãoSobrecarga dos Operadores [] e ()Operadores de Conversão de TipoRecapitulação - Classe Matrix9Templates
Templates de FunçõesTemplates de ClassesEspecialização de TemplatesTemplates VariádicosNoções Básicas de SFINAE e Traits de TiposRecapitulação - Contêiner GenéricoPratique por conta própria: Compilador de C++ online