Quais são as diferenças entre struct e classe em C ++?


439

Esta pergunta foi feita no contexto de C # / .Net .

Agora eu gostaria de aprender as diferenças entre uma estrutura e uma classe em C ++. Por favor, discuta as diferenças técnicas e os motivos para escolher uma ou outra no design do OO.

Vou começar com uma diferença óbvia:

  • Se você não especificar public:ou private:, os membros de uma estrutura serão públicos por padrão; os membros de uma classe são privados por padrão.

Tenho certeza de que existem outras diferenças nos cantos obscuros da especificação C ++.


6
Este link resume bem as diferenças.
Sjsam # 7/15

1
Por que todas as pessoas usam struct para construir uma árvore? Porque parece que a diferença não é muito. BTW, que é um ótimo site @ sjsam.
JW.ZG

1
Procurando a diferença entre structC e C ++? Veja aqui .
Marc.2377

@ JW.ZG Nem "todas" as pessoas fazem! Aqueles que fazem isso simplesmente preferem ou não percebem o que structsignifica em C ++. ;) Mas não há motivo para você não usar a classpalavra - chave.
Lightness Races in Orbit

Respostas:


465

Você esquece a complicada segunda diferença entre classes e estruturas.

Quoth o padrão (§11.2.2 em C ++ 98 a C ++ 11):

Na ausência de um acesso de especificador para uma classe base, público é assumido quando a classe derivada é declarado struct e privado é assumida quando a classe é declarada classe .

E apenas por uma questão de completude, a diferença mais conhecida entre classe e estrutura é definida em (11.2):

O membro de uma classe definida com a classe de palavra-chave é privado por padrão. Os membros de uma classe definida com as palavras-chave struct ou union são públicos por padrão.

Diferença adicional: a palavra-chave classpode ser usada para declarar parâmetros do modelo, enquanto a structpalavra - chave não pode ser usada.


22
Essa não é realmente uma segunda diferença, é só que a pergunta declarou a diferença incompletamente. Todos os subobjetos são privados por padrão ao usar class, public por padrão com structe ambos definem um tipo de classe.
Ben Voigt

10
Acho que você não entendeu, Ben. É a herança que é pública para estruturas e privada para classes. Essa é uma distinção muito importante e completamente sem relação com o acesso real dos membros. Por exemplo, o idioma poderia muito bem ter definido o contrário, por exemplo, ambos são herdados publicamente por padrão e você teria implicações muito diferentes.
Assaf Lavie

104
Na verdade, a verdadeira diferença complicada entre structe classé que o último pode ser usado no lugar de a typenamepara declarar um parâmetro de modelo, enquanto o primeiro não. :)
Sbi

21
@ MrUniverse: Isso é totalmente errado. (Há uma escola que usa isso para uma convenção, mas não é sintaticamente aplicadas.)
SBI

3
@sbi "a verdadeira diferença complicada entre struct e classe" - Bonitinha, mas a pergunta é sobre a diferença entre uma estrutura e uma classe, não sobre as diferenças nas quais as palavras-chave podem ser usadas.
Jim Balter

161

Citando o FAQ do C ++ ,

[7.8] Qual é a diferença entre as palavras-chave struct e classe?

Os membros e as classes base de uma estrutura são públicos por padrão, enquanto na classe, eles são privados. Nota: você deve tornar suas classes base explicitamente públicas, privadas ou protegidas, em vez de confiar nos padrões.

Struct e classe são funcionalmente equivalentes.

OK, chega dessa conversa limpa e estridente. Emocionalmente, a maioria dos desenvolvedores faz uma forte distinção entre uma classe e uma estrutura. Uma estrutura simplesmente parece uma pilha aberta de bits com muito pouco em termos de encapsulamento ou funcionalidade. Uma classe se sente como um membro vivo e responsável da sociedade, com serviços inteligentes, uma forte barreira de encapsulamento e uma interface bem definida. Como essa é a conotação que a maioria das pessoas já tem, você provavelmente deve usar a palavra-chave struct se tiver uma classe que possui muito poucos métodos e dados públicos (essas coisas existem em sistemas bem projetados!), Mas, caso contrário, você provavelmente deve usar a classe palavra-chave


123

Vale lembrar as origens do C ++ e a compatibilidade com o C.

C tem estruturas, não tem conceito de encapsulamento, então tudo é público.

Ser público por padrão geralmente é considerado uma má idéia ao adotar uma abordagem orientada a objetos; portanto, ao criar uma forma de C que seja nativamente favorável ao OOP (você pode fazer OO em C, mas não vai ajudá-lo), esse foi o No C ++ (originalmente "C With Classes"), faz sentido tornar os membros privados por padrão.

Por outro lado, se o Stroustrup tivesse alterado a semântica structpara que seus membros fossem privados por padrão, ele teria uma compatibilidade quebrada (não é mais tão verdadeira quanto os padrões divergiam, mas todos os programas C válidos também eram programas C ++ válidos, que teve um grande efeito em dar suporte ao C ++).

Portanto, uma nova palavra-chave classfoi introduzida para ser exatamente como uma estrutura, mas privada por padrão.

Se o C ++ tivesse surgido do zero, sem histórico, provavelmente teria apenas uma dessas palavras-chave. Provavelmente também não teria causado o impacto que causou.

Em geral, as pessoas tendem a usar struct quando estão fazendo algo como como as estruturas são usadas em C; membros públicos, nenhum construtor (contanto que não esteja em uma união, você pode ter construtores em estruturas, assim como as classes, mas as pessoas tendem a não), nenhum método virtual etc. as pessoas que leem o código para instruir as máquinas (ou então ficaríamos com os opcodes de montagem e de VM brutos) é uma boa ideia ficar com isso.


Provavelmente também vale a pena notar que era provavelmente mais fácil ter classes e estruturas funcionando da mesma maneira, do que ter uma diferença fundamental. Em retrospecto, pode ter havido algum benefício em, por exemplo, especificar que qualquer coisa declarada como uma estrutura deve ser um PODS (ou seja, proibir estruturas de ter membros virtuais, construtores ou destruidores padrão não triviais, etc.), mas isso não é do meu conhecimento. já foi exigido por qualquer padrão ou implementação C ++.
Supercat

1
@ supercat o fato de ser uma linguagem OO em que um vasto repertório de programas escritos em uma linguagem não-OO eram programas válidos, trouxe o conceito à tona e parece surgir mais lá do que em idiomas mais puramente OO (e, é claro, é realmente definido no padrão). A história do início do C ++ definitivamente explica muito sobre isso. Stroustrup, "O design e a evolução do C ++", é uma leitura interessante.
Jon Hanna

1
Eu percebo uma guerra religiosa entre pessoas que acham que tudo o que não é "oop-ish" deveria ser, e aqueles que pensam que a OOP deveria ser considerada uma ferramenta, mas não a ferramenta. C ++ certamente parece abraçar a última filosofia, mas eu realmente não sei muito sobre linguagens antes dela. Minha própria filosofia é que, quando alguém quer um objeto, deve usá-lo, e quando deseja uma agregação de variáveis ​​relacionadas, mas independentes, deve usá-lo. O C ++ não faz distinção sintática entre esses tipos de coisas, e o .NET tenta embaçar essa distinção, mas o pouco que eu conheço de D ...
supercat

1
... sugere que o reconhece mais do que C ++ ou .NET. Agregações de variáveis ​​não são exatamente OOPish, mas isso não significa que elas não devam ser empregadas quando úteis .
Supercat

3
Não concordo com "C tem estruturas, não tem conceito de encapsulamento, então tudo é público.", Você pode ocultar a definição de um structdentro de um *.carquivo -File e permitir que outras unidades de tradução o usem apenas com um ponteiro. Então você tem um encapsulamento ainda mais forte, porque outras unidades de tradução nem sabem o que está dentro do struct.
12431234123412341234123

32

Os membros da classe são privados por padrão. Os membros do Struct são públicos por padrão. Além disso, não há outras diferenças. Veja também esta pergunta .


15
Não apenas membros, mas todo o acesso, incluindo herança.
Nemanja Trifunovic

4
Bem, eu diria que a outra diferença é a semântica. Struct para muitas pessoas os faz pensar "estrutura de dados" como uma sobra de C.
Kris Kumler

3
@KrisKumler: Esses não são "semânticos"; eles são sentimentos pessoais. Ambos structe classdeclaram uma classe com semântica idêntica (não obstante a interpretação por partes do corpo da definição).
Corridas de leveza em órbita

28

De acordo com Stroustrup na linguagem de programação C ++ :

O estilo que você usa depende das circunstâncias e do gosto. Eu geralmente prefiro usar structpara classes que têm todos os dados públicos. Penso nessas classes como "tipos não muito adequados, apenas estruturas de dados".

Funcionalmente, não há outra diferença senão o público / privado


32
Que diferença? Por favor explique.
Crashmstr 16/06/09

10

STRUCT é um tipo de Tipo de Dados Abstrato que divide um determinado pedaço de memória de acordo com a especificação da estrutura. As estruturas são particularmente úteis na serialização / desserialização de arquivos, pois a estrutura pode ser gravada no arquivo literalmente. (ou seja, obtenha um ponteiro para a estrutura, use a macro SIZE para calcular o número de bytes a serem copiados e mova os dados para dentro ou para fora da estrutura.)

As classes são um tipo diferente de tipo de dados abstratos que tentam garantir a ocultação de informações. Internamente, pode haver uma variedade de maquinações, métodos, variáveis ​​temporárias, variáveis ​​de estado. etc., todos usados ​​para apresentar uma API consistente para qualquer código que deseje usar a classe.

Com efeito, estruturas são sobre dados, classes são sobre código.

No entanto, você precisa entender que essas são apenas abstrações. É perfeitamente possível criar estruturas que se parecem muito com classes e classes que se parecem muito com estruturas. De fato, os primeiros compiladores C ++ eram meramente pré-compiladores que convertem o código C ++ em C. Portanto, essas abstrações são um benefício para o pensamento lógico, não necessariamente um ativo para o próprio computador.

Além do fato de que cada um é um tipo diferente de abstração, as Classes fornecem soluções para o quebra-cabeça de nomeação de código C. Como você não pode ter mais de uma função exposta com o mesmo nome, os desenvolvedores costumavam seguir um padrão de _ (). por exemplo, mathlibextreme_max (). Ao agrupar APIs em classes, funções semelhantes (aqui as chamamos de "métodos") podem ser agrupadas e protegidas da nomeação de métodos em outras classes. Isso permite que o programador organize melhor seu código e aumente sua reutilização. Em teoria, pelo menos.


1
Essa é a coisa mais óbvia sobre estruturas e classes. "Structs está prestes dados, as aulas são sobre o código" pode ser reformulada como "estruturas são sobre os dados, as aulas são sobre os dados, segurança e operações realizadas nesses dados"
Arun Aravind

3
Não é possível criar uma estrutura em C ++. Só é possível criar uma classe usando a structpalavra-chave herdada .
Lightness Races in Orbit em

1
Esta resposta não parece ser sobre C ++. Em C ++, structdeclara classes (incluindo public/ private/ protected, herança, etc).
Melpomene #

Como as estruturas são abstratas? A gravação de estruturas brutas em um arquivo está repleta de problemas, mesmo em C (os problemas usuais incluem preenchimento, endianness, tamanho de palavra diferente etc.). De que SIZEmacro você está falando?
Melpomene #

10

1) Membros de uma classe são privados por padrão e membros de struct são públicos por padrão.

Por exemplo, o programa 1 falha na compilação e o programa 2 funciona bem.

// Program 1
#include <stdio.h>

class Test {
    int x; // x is private
};
int main()
{
  Test t;
  t.x = 20; // compiler error because x is private
  getchar();
  return 0;
}
Run on IDE
// Program 2
#include <stdio.h>

struct Test {
    int x; // x is public
};
int main()
{
  Test t;
  t.x = 20; // works fine because x is public
  getchar();
  return 0;
}

2) Ao derivar uma estrutura de uma classe / estrutura, o especificador de acesso padrão para uma classe / estrutura base é público. E ao derivar uma classe, o especificador de acesso padrão é privado.

Por exemplo, o programa 3 falha na compilação e o programa 4 funciona bem.

// Program 3
#include <stdio.h>

class Base {
public:
    int x;
};

class Derived : Base { }; // is equilalent to class Derived : private Base {}

int main()
{
  Derived d;
  d.x = 20; // compiler error becuase inheritance is private
  getchar();
  return 0;
}
Run on IDE
// Program 4
#include <stdio.h>

class Base {
public:
    int x;
};

struct Derived : Base { }; // is equilalent to struct Derived : public Base {}

int main()
{
  Derived d;
  d.x = 20; // works fine becuase inheritance is public
  getchar();
  return 0;
}

Removi exemplos de código 7/3 como mencionado por peritos
Suraj K Thomas

8

A única outra diferença é a herança padrão de classes e estruturas, que, sem surpresa, é privada e pública, respectivamente.


5
  1. Os membros de uma estrutura são públicos por padrão, os membros da classe são privados por padrão.
  2. A herança padrão para a Estrutura de outra estrutura ou classe é pública. A herança padrão para a classe de outra estrutura ou classe é privada.
class A{    
public:    
    int i;      
};

class A2:A{    
};

struct A3:A{    
};


struct abc{    
    int i;
};

struct abc2:abc{    
};

class abc3:abc{
};


int _tmain(int argc, _TCHAR* argv[])
{    
    abc2 objabc;
    objabc.i = 10;

    A3 ob;
    ob.i = 10;

    //A2 obja; //privately inherited
    //obja.i = 10;

    //abc3 obss;
    //obss.i = 10;
}

Isso está no VS2005.


_tmainnão é C ++ padrão.
Melpomene #

4

Não na especificação, não. A principal diferença está nas expectativas dos programadores quando eles leem seu código em 2 anos. estruturas são freqüentemente assumidas como POD. As estruturas também são usadas na metaprogramação de modelos quando você define um tipo para outros fins que não a definição de objetos.


4

Outra coisa a observar, se você atualizou um aplicativo herdado que possui estruturas para usar classes, pode encontrar o seguinte problema:

O código antigo possui estruturas, o código foi limpo e elas foram alteradas para classes. Uma função virtual ou duas foram adicionadas à nova classe atualizada.

Quando as funções virtuais estão nas classes, internamente, o compilador adicionará um ponteiro extra aos dados da classe para apontar para as funções.

Como isso quebraria o código legado antigo, se no código antigo em algum lugar a estrutura foi limpa usando o memfill para limpar tudo em zeros, isso também afetaria os dados extras do ponteiro.


1
O código que usa o memfill para limpar uma estrutura provavelmente possui outros hábitos ofensivos. Vá com cautela.
21715 David Thornley

@DavidThornley: O uso de um preenchimento zero para apagar ou inicializar uma estrutura de dados é padrão em C. Em um projeto de linguagem mista, não se pode esperar que o código na parte C evite a callocfavor new. Tudo o que se pode fazer é tentar garantir que quaisquer estruturas usadas pela parte C do código sejam de fato PODS.
Super dec

4
  1. O membro de uma classe definida com a palavra-chave classé privatepor padrão. Os membros de uma classe definida com as palavras-chave struct(ou union) são publicpor padrão.

  2. Na ausência de um especificador de acesso para uma classe base, publicé assumido quando a classe derivada é declarada structe privateé assumido quando a classe é declarada class.

  3. Você pode declarar um, enum classmas não um enum struct.

  4. Você pode usar, template<class T>mas não template<struct T>.

Observe também que o padrão C ++ permite que você declare um tipo como a structe use-o classao declarar o tipo e vice-versa. Além disso, std::is_class<Y>::valueé truepara Y ser um structe a class, mas é falsepara um enum class.


resposta agradável, embora eu estou em falta uma clara inconfundível 0) a diferença entre structe classem C ++ é uma diferença entre palavras-chave, não entre tipos de dados (ou alguma alternativa melhor;)
idclev 463035818

@ formerlyknownas_463035818: Mas você não acha std::is_class<Y>::valueque cobre isso?
Bathsheba

Sim, apenas pensei que poderia ser mais proeminente, porque esse é o mal-entendido comum e, uma vez que está fora do caminho, o resto são apenas corolários.
Idclev 463035818

Não importa, a sua resposta é perfeito como é, eu escrevi um outro, ferido doesnt ter um mais
idclev 463035818

4

A diferença entre classe structé uma diferença entre palavras-chave, não entre tipos de dados. Esses dois

struct foo : foo_base { int x;};
class bar : bar_base { int x; };

ambos definem um tipo de classe. A diferença das palavras-chave neste contexto é o acesso padrão diferente:

  • foo::xé público e foo_baseé herdado publicamente
  • bar::xé privado e bar_baseé herdado em particular

2

Aqui está uma boa explicação: http://carcino.gen.nz/tech/cpp/struct_vs_class.php

Portanto, mais uma vez: em C ++, uma estrutura é idêntica a uma classe, exceto que os membros de uma estrutura têm visibilidade pública por padrão, mas os membros de uma classe têm visibilidade privada por padrão.


2

É apenas uma convenção. Estruturas podem ser criadas para armazenar dados simples, mas depois evoluem o tempo com a adição de funções-membro e construtores. Por outro lado, é incomum ver algo que não seja público: acesso em uma estrutura.


2

ISO IEC 14882-2003

9 aulas

§3

Uma estrutura é uma classe definida com a chave de classe struct ; seus membros e classes base (cláusula 10) são públicos por padrão (cláusula 11).


2

Outra diferença principal é quando se trata de modelos. Tanto quanto eu sei, você pode usar uma classe ao definir um modelo, mas NÃO uma estrutura.

template<class T> // OK
template<struct T> // ERROR, struct not allowed here

1
Se você pretendeu enfatizar que as estruturas não podem ser usadas como tipos generalizados, você está errado. E isso structnão é permitido apenas por convenção (é melhor dizer que a classpalavra - chave é usada em sentido diferente aqui, consulte Usar 'classe' ou 'typename' para parâmetros de modelo ).
dma_k

A palavra-chave não é permitida lá, mas você pode passar em uma classe que você definiu structmuito bem. Simplesmente tente. struct T{}; template <typename T> void foo() {} foo<T>();
Lightness Races em órbita

1

As outras respostas mencionaram os padrões público / privado (mas observe que uma estrutura é uma classe é uma estrutura; elas não são dois itens diferentes, apenas duas maneiras de definir o mesmo item).

O que pode ser interessante notar (principalmente porque o solicitante provavelmente está usando o MSVC ++, pois menciona C ++ "não gerenciado") é que o Visual C ++ reclama em determinadas circunstâncias se uma classe é declarada com classe depois definida com struct(ou possivelmente o contrário) ), embora a norma diga que é perfeitamente legal.


Sei que é um comentário muito tardio, mas esteja ciente de que o aviso acima mencionado não é sem mérito, pois a ABI do Windows manipula estruturas e classes de maneira diferente e, portanto, misturar (encaminhar) declarações de classe e estrutura pode realmente levar a problemas de vinculação difíceis de entender!
MFH 03/09

1
  • . Nas classes, todos os membros por padrão são privados, mas na estrutura os membros são públicos por padrão.

    1. Não há termo como construtor e destruidor para estruturas, mas para o compilador de classes cria o padrão se você não fornecer.

    2. O tamanho da estrutura vazia é 0 Bytes e o tamanho da classe vazia é 1 Byte O tipo de acesso padrão da estrutura é público. Uma estrutura normalmente deve ser usada para agrupar dados.

    O tipo de acesso padrão da classe é privado e o modo padrão de herança é privado. Uma classe deve ser usada para agrupar dados e métodos que operam nesses dados.

    Em resumo, a convenção é usar struct quando o objetivo é agrupar dados e usar classes quando exigirmos abstração de dados e, talvez, herança.

    No C ++, estruturas e classes são passadas por valor, a menos que seja explicitamente referenciado. Em outras línguas, classes e estruturas podem ter semântica distinta - ie. objetos (instâncias de classes) podem ser passados ​​por referência e estruturas podem ser passadas por valor. Nota: existem comentários associados a esta pergunta. Veja a página de discussão para adicionar à conversa.


3
"2. A estrutura vazia de Sizeof é 0 Bytes, enquanto a classe vazia de Sizeof é 1 Byte". Falso. Acabei de testar com g++. Você pode estar pensando em Otimização da Base Vazia, mas isso se aplica a ambos também.
precisa saber é o seguinte

1
Não é verdade. Em C ++, o tamanho de uma estrutura vazia é 1. Em C, uma estrutura vazia não é permitida. GCC permite estruturas vazias em C como uma extensão do compilador e tal estrutura tem um tamanho 0.
Johan Råde

Esta resposta está errada. Além do tamanho, a parte construtor / destruidor também é imprecisa: estruturas podem ter construtores e destruidores muito bem. De fato, structcria classes completas em C ++.
Melpomene #

1

Embora implícito em outras respostas, não é mencionado explicitamente - que as estruturas são compatíveis com C, dependendo do uso; classes não são.

Isso significa que, se você estiver escrevendo um cabeçalho que deseja ser compatível com C, não terá outra opção além de struct (que no mundo C não pode ter funções; mas pode ter ponteiros de função).


-1

Você pode considerar isso para obter diretrizes sobre quando escolher uma estrutura ou classe, https://msdn.microsoft.com/en-us/library/ms229017%28v=vs.110%29.aspx .

√ CONSIDERAM definir uma estrutura em vez de uma classe se as instâncias do tipo são pequenas e geralmente têm vida curta ou são incorporadas em outros objetos.

X EVITE definir uma estrutura, a menos que o tipo tenha todas as seguintes características:

Representa logicamente um valor único, semelhante aos tipos primitivos (int, double, etc.).

Tem um tamanho de instância com menos de 16 bytes.

É imutável.

Não precisará ser embalado com freqüência.


Isso é sobre .NET / C #, não C ++.
Melpomene #

-2

A classe é significativa apenas no contexto da engenharia de software. No contexto de estruturas e algoritmos de dados, classe e estrutura não são tão diferentes. Não há nenhuma regra restrita que o membro da classe deva ser referenciado.

Ao desenvolver um projeto grande com toneladas de pessoas sem classe, você pode finalmente obter um código acoplado complicado, porque todos usam as funções e os dados que desejam. A classe fornece controles de permissão e inerentes para aprimorar a dissociação e a reutilização de códigos.

Se você ler alguns princípios de engenharia de software, verá que a maioria dos padrões não pode ser implementada facilmente sem aula. por exemplo: http://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29

BTW, Quando uma estrutura aloca uma restrição de memória e inclui várias variáveis, as variáveis ​​de tipo de valor indicam que os valores estão incorporados no local em que a estrutura está alocada. Por outro lado, os valores da variável do tipo de referência são externos e são referenciados por um ponteiro que também é incorporado no local onde struct está alocado.


Esta resposta não parece ser sobre C ++. Em C ++, structdeclara classes (incluindo controles de permissão, herança etc.).
Melpomene #

-3

A diferença entre palavras-chave struct e class em C ++ é que, quando não há especificador específico em determinado tipo de dados compostos, por padrão struct ou union são as palavras-chave públicas que apenas consideram a ocultação de dados, mas class é a palavra-chave privada que considera a ocultação do programa. códigos ou dados. Sempre alguns programadores usam struct para dados e classe por causa de código. Para mais informações, entre em contato com outras fontes.


O OP já mencionou que os structmembros são públicos por padrão, e a resposta aceita em 2009 menciona herança. Por que escrever outra resposta que não acrescenta novas informações quatro anos depois?
Melpomene #

-3

De todos esses fatores, pode-se concluir que o conceito de Classe é altamente adequado para representar objetos do mundo real, em vez de "Estruturas" .Em grande parte porque os conceitos de POO usados ​​na classe são altamente práticos na explicação de cenários do mundo real, portanto, mais fáceis de mesclá-los à realidade. Por exemplo, a herança padrão é pública para estruturas, mas se aplicarmos essa regra ao mundo real, isso é ridículo. Mas em uma classe a herança padrão é privada, o que é mais realista.

De qualquer forma, o que preciso justificar é que Classe é um conceito aplicável no mundo real muito mais amplo, enquanto que Estrutura é um conceito primitivo com organização interna ruim (Eventhough struct segue os conceitos de OOP, eles têm um significado ruim)


1
Como a herança privada é "mais realista"? A maioria das linguagens de programação nem sequer tem o conceito de herança privada.
Melpomene #

-3

A principal diferença entre a estrutura e a palavra-chave class em ops é que, nenhuma declaração de membro pública e privada presente na estrutura. E o membro de dados e a função de membro podem ser definidos como público, privado e também protegido.


Esta resposta não parece ser sobre C ++. Em C ++, structdeclara classes (incluindo public/ private/ protected, herança, etc).
Melpomene #

-3

** UPDATE: ** Por favor, ignore esta resposta. Não considerei a possibilidade de que, para o struct, o valor não tivesse sido inicializado, mas por acaso fosse 0. Não há uma diferença de inicialização entre o struct e a classe.


Estou vendo outra diferente entre estruturas e classes relacionadas à inicialização padrão.

struct Foo {
    int a;
};

class Bar {
    int a;
};

class Tester {
    Foo m_Foo = Foo();
    Bar m_Bar = Bar();

public:
    Tester() {}
};

int main() {
    auto myTester = Tester();
}

Execute esse código e examine o myTester. Você verá que para m_Foo, a estrutura m_Foo.a foi inicializada como 0, mas para m_Bar, a classe m_Bar.a não foi inicializada. Portanto, parece haver uma diferença no que o construtor padrão faz para struct vs. classe. Estou vendo isso com o Visual Studio.


1
Como você determinou que m_Foo.afoi inicializado? E se não fosse inicializado e acontecesse 0?
melpomene

Uhhh, eu não fiz. Foi mal. Esta não é uma diferença entre struct e classe. As características de inicialização são as mesmas.
Eric Hill

-4

A principal diferença entre struct e classe é que, em struct, você pode declarar apenas variáveis ​​de dados de diferentes tipos de dados, enquanto na classe você pode declarar variáveis ​​de dados, funções-membro e, portanto, pode manipular variáveis ​​de dados por meio de funções.

-> outra coisa útil que eu acho na classe versus estrutura é que, ao implementar arquivos em um programa, se você deseja fazer algumas operações de uma estrutura repetidas vezes a cada novo conjunto de operações, você precisa criar uma função separada e precisa passa o objeto de struct depois de lê-lo do arquivo para fazer algumas operações nele. Enquanto estiver na aula, se você criar uma função que faça algumas operações com os dados necessários todas as vezes ... é fácil, basta ler o objeto do arquivo e chamar a função

Mas depende do programador de que maneira ele / ela considera adequado ... de acordo com mim, eu prefiro a aula toda vez que suporta OOPs e é por isso que ela é implementada em quase todas as linguagens e é o recurso maravilhoso de toda a programação em tempo; )

E sim, a diferença mais inesquecível que esqueci de mencionar é que a classe suporta ocultação de dados e também suporta operações que são executadas em tipos de dados incorporados, enquanto o struct não!


1
Em C ++ structpode ter funções de membro
Chtz

@chtz Obrigado ... eu tenho que saber sobre este recurso só agora .. muito obrigado .. im apenas um iniciante não tão especialista como você-lo no futuro também precisa de conselhos de u guys :-)
Yug Rawal

e, na verdade, a função de membro deve ser pretendida em seu significado mais amplo. structpode ter construtores, função de membro e distrator (possivelmente virtual, possivelmente privado, protegido ou público). Eles podem herdar e ser herdados. então, na verdade ... tudo o que uma classe pode ter. uma convenção típica é declarar com struct o que você teria declarado como struct em C e como classe se declararmos variável privada e protegida, funções virtuais, ctor e dtor e assim por diante. Mas é apenas uma convenção, não imposta pela linguagem
Gian Paolo

-5

Eu encontrei outra diferença. se você não definir um construtor em uma classe, o compilador definirá um. mas em uma estrutura, se você não definir um construtor, o compilador também não definirá um construtor. portanto, em alguns casos, na verdade, não precisamos de um construtor, struct é uma escolha melhor (dica de desempenho). e desculpe pelo meu inglês ruim.


4
Isso não é verdade. Não há diferença entre uma classe definida com a structpalavra - chave e uma classe definida com a classpalavra - chave a esse respeito.
ymett

Quando eu uso uma estrutura sem um construtor, obtenho uma velocidade melhor do que uma classe sem um construtor.
Ali

@ Ali Não, você não.
Lightness Races em órbita

-5

Classes são tipos de referência e estruturas são tipos de valores.
Quando digo que Classes são tipos de referência,
basicamente elas conterão o endereço de uma variável de instância.

Por exemplo:

Class MyClass
{
    Public Int DataMember;  //By default, accessibility of class data members 
                            //will be private. So I am making it as Public which 
                            //can be accessed outside of the class.
}

No método principal,
posso criar uma instância dessa classe usando o novo operador que aloca memória para essa classe
e armazena o endereço base na variável do tipo MyClass (_myClassObject2).

Static Public void Main (string[] arg)
{
    MyClass _myClassObject1 = new MyClass();
    _myClassObject1.DataMember = 10;

    MyClass _myClassObject2 = _myClassObject1;
    _myClassObject2.DataMember=20;
}

No programa acima, MyClass _myClassObject2 = _myClassObject1; A instrução indica que ambas as variáveis ​​do tipo MyClass

  1. myClassObject1
  2. myClassObject2

e apontará para o mesmo local de memória.
Basicamente, atribui o mesmo local de memória a outra variável do mesmo tipo.

Portanto, se qualquer alteração que fizermos em qualquer um dos objetos, digite MyClass, terá efeito sobre outro,
pois ambos apontam para o mesmo local de memória.

"_myClassObject1.DataMember = 10;" nessa linha, os membros de dados do objeto conterão o valor 10.
"_myClassObject2.DataMember = 20;" nessa linha, o membro de dados do objeto conterá o valor de 20.
Eventualmente, estamos acessando de um objeto por meio de ponteiros.

Diferentemente das classes, as estruturas são tipos de valor. Por exemplo:

Structure MyStructure
{
    Public Int DataMember;  //By default, accessibility of Structure data 
                            //members will be private. So I am making it as 
                            //Public which can be accessed out side of the structure.
}

Static Public void Main (string[] arg)
{
    MyStructure _myStructObject1 = new MyStructure();
    _myStructObject1.DataMember = 10;

    MyStructure _myStructObject2 = _myStructObject1;
    _myStructObject2.DataMember = 20;
}

No programa acima,
instanciar o objeto do tipo MyStructure usando o novo operador e
armazenar o endereço na variável _myStructObject do tipo MyStructure e
atribuir o valor 10 ao membro de dados da estrutura usando "_myStructObject1.DataMember = 10".

Na próxima linha,
estou declarando outra variável _myStructObject2 do tipo MyStructure e atribuindo _myStructObject1 a isso.
Aqui, o compilador .NET C # cria outra cópia do objeto _myStructureObject1 e
atribui esse local de memória à variável MyStructure _myStructObject2.

Portanto, qualquer alteração que fizermos em _myStructObject1 nunca terá efeito em outra variável _myStructObject2 do tipo MyStructrue.
É por isso que estamos dizendo que Estruturas são tipos de valor.

Portanto, a classe Base imediata para a classe é Object e a classe Base imediata para Structure é ValueType que herda de Object.
As classes apoiarão uma herança, enquanto as estruturas não.

Como estamos dizendo isso?
E qual é a razão por trás disso?
A resposta é Classes.

Pode ser abstrato, selado, estático e parcial e não pode ser Privado, Protegido e protegido interno.


4
Eu acho que isso está tentando responder a pergunta para c #? A questão é sobre c ++, e isso torna essa resposta imprecisa, certo?
smw

@ smw absolutamente, ele escreveu seu código de exemplo em C # e eu vim aqui para verificar se não havia diferença na passagem de parâmetros entre C ++ structe class. Ninguém aqui mencionou, nem toda a web. Portanto, também não acho que isso se aplique ao C ++.
John

Isso nem é um código C # válido - as palavras-chave estão todas erradas. "Público", "Estático", "Int" e "Classe" não devem ser capitalizados e devem ser "struct" e não "Estrutura". Descrição é geralmente correcta para C # (embora estruturas podem interfaces de ainda herdar, não apenas outras estruturas), mas não responde à questão, uma vez que estava prestes C ++ ...
Darrel Hoffman

2
Esta resposta é um absurdo completo. Ele usa uma mistura estranha de Visual Basic e C # para seus exemplos de código, e o conjunto "Classes are Reference types e Structures are Values ​​types" ... só se aplica ao .NET (isto é, C #) e não ao C ++. Você está no quarto errado, cara. É aqui que você pertence: stackoverflow.com/questions/13049
TheFlash 20/15

Mas essa resposta indica que o mesmo é válido para C (++), que as estruturas são usadas como tipos de valor. int a = 3; int b = a;e semelhanteMyStruct a=MyStruct("data"); MyStruct b = a;
luckydonald 29/01

-8

Existem 3 diferenças básicas entre estrutura e classe

A memória 1St- é reservada para a estrutura na memória da pilha (que fica próxima à linguagem de programação), independentemente da classe na memória da pilha ser reservada apenas para armazenamento e a memória real ser reservada na memória de pilha.

2º - Por padrão, a estrutura trata como público se a classe é tratada como privada.

3Rd - não é possível reutilizar o código na estrutura, mas na classe podemos reutilizar o mesmo código em muitas vezes chamado de herança


2
Estruturas C ++ suportam herança e métodos abstratos. Estrutura e classe são alocadas da mesma maneira. Alocar classe no heap, mesmo que não sejam instanciadas com um "novo", não faz sentido para sistemas embarcados.
JCMS 5/03/2015

2
# 1 também está errado. A pilha é usada quando você declara algo desse tipo como uma variável local e a pilha é usada quando você usa o operador "novo".
Score_Und
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.