Vou adicionar às respostas existentes porque o C ++ moderno agora é uma coisa e as Diretrizes Principais oficiais foram criadas para ajudar com questões como essas.
Esta é uma seção relevante das diretrizes:
C.2: Use classe se a classe tiver um invariante; use struct se os membros de dados puderem variar independentemente
Uma invariante é uma condição lógica para os membros de um objeto que um construtor deve estabelecer para que as funções de membro público assumam. Depois que o invariante é estabelecido (normalmente por um construtor), cada função de membro pode ser chamada para o objeto. Um invariante pode ser declarado informalmente (por exemplo, em um comentário) ou mais formalmente usando Expects.
Se todos os membros de dados podem variar independentemente uns dos outros, nenhum invariante é possível.
Se uma classe tiver dados privados, um usuário não pode inicializar completamente um objeto sem o uso de um construtor. Portanto, o definidor de classe fornecerá um construtor e deve especificar seu significado. Isso efetivamente significa que o definidor precisa definir um invariante.
Execução
Procure structs com todos os dados privados e classes com membros públicos.
Os exemplos de código fornecidos:
struct Pair { // the members can vary independently
string name;
int volume;
};
// but
class Date {
public:
// validate that {yy, mm, dd} is a valid date and initialize
Date(int yy, Month mm, char dd);
// ...
private:
int y;
Month m;
char d; // day
};
Class
s funcionam bem para membros que são, por exemplo, derivados uns dos outros ou inter-relacionados. Eles também podem ajudar na verificação de sanidade na instanciação.Struct
s funcionam bem para ter "pacotes de dados", onde nada de especial está realmente acontecendo, mas os membros logicamente fazem sentido serem agrupados.
A partir disso, faz sentido que class
existam para suportar encapsulamento e outros conceitos de codificação relacionados, para os quais struct
os programas simplesmente não são muito úteis.