Duvida questão de concurso C++

Segue a questão:

01: class C
02: {
03: int i;
04:
05: public:
06: C() {}
07: ~C() {}
08: int j;
09: void set(int v) {i = v;}
10: int get() { return i; }
11: };
12:
13: int main()
14: {
15: C c;
16: c.set(3);
17: c.j = 4;
18: return 0;
19: }

Sobre esse trecho de código, considere as afirmativas a seguir.
I. O atributo da linha 03 é private.
II. A linha 15 cria um objeto.
III. A linha 16 causará erro de execução.
IV. A linha 17 causará erro de compilação.
Assinale a alternativa correta.
a) Somente as afirmativas I e II são corretas.
b) Somente as afirmativas I e IV são corretas.
c) Somente as afirmativas III e IV são corretas.
d) Somente as afirmativas I, II e III são corretas.
e) Somente as afirmativas II, III e IV são corretas.

A resposta correta é a “a”, porem ela afirma que isto: C c cria um objeto, porem isto não instanciado. Não estaria errada esta alternativa?

Em C++ você não tem a necessidade de instanciar objetos como no Java, porém o ciclo de vida do objeto fica restrito ao escopo. Para criar um objeto instanciado devemos usar o operador new, que nem no Java, porém a variável de referência deve ser um ponteiro, sendo assim:

C* c = new C();

Quando não usamos ponteiros, automágicamente o C++ já cria um objeto, como esta ai em cima na questão.

Outra coisa, como em C++ não temos garbage collector por padrão (existem algumas implementações), devemos destruir o objeto, que se não me falhe a memória é assim:

delete c;

No C++, existe a diferença entre criar objetos no Heap (com new) e no Stack (sem new). A sintaxe indicada na alternativa refere-se a segunda opção. E vai haver instanciação sim.

Isso só vale para objetos criados com new. No caso dos criados no stack, eles são automagicamente destruídos quando saem de escopo também. :slight_smile:

Só um detalhezinho.

Em C++, há uma diferença entre a instanciação e a inicialização de campos de objetos que deve ser levada em conta na hora de programar.

Em C++, variáveis de instância de tipos primitivos, assim como ponteiros, não são inicializados automaticamente (tradução: vêm com lixo). E você deve tomar muito cuidado com isso. Qual é a saída do seguinte programa, dada a definição da classe C do sua questão?

int main()  
{  
    C c;  
    printf ("%d\n", c.j);
    fflush (stdout);
    return 0;
} 

Escolha uma das alternativas abaixo.

  1. c.j deve conter o valor 0, então deve imprimir “0”
  2. c.j deve conter o valor 0xCCCCCCCC, então deve imprimir o valor “-858993460”
  3. c.j pode conter qualquer lixo contido na memória, então não podemos prever qual a saída desse programa

A resposta 1 é escolhida por gente que veio do Java e está aprendendo C++ agora. Ela está errada porque o código gerado para a instanciação de objetos não faz a inicialização de campos primitivos.
A resposta 2 é escolhida por gente que só debuga o programa em modo Debug e nunca rodou o programa compilado em modo Release. Em modo Debug, muitos compiladores, para garantir que o programa sempre rode “deterministicamente” (para poder facilitar a depuração), completam os campos com um valor fixo e que é difícil de ocorrer em um modo normal de execução.
A resposta 3 é a correta.

[quote=entanglement]Só um detalhezinho.

Em C++, há uma diferença entre a instanciação e a inicialização de campos de objetos que deve ser levada em conta na hora de programar.

Em C++, variáveis de instância de tipos primitivos, assim como ponteiros, não são inicializados automaticamente (tradução: vêm com lixo). E você deve tomar muito cuidado com isso. Qual é a saída do seguinte programa, dada a definição da classe C do sua questão?

int main()  
{  
    C c;  
    printf ("%d\n", c.j);
    fflush (stdout);
    return 0;
} 

Escolha uma das alternativas abaixo.

  1. c.j deve conter o valor 0, então deve imprimir “0”
  2. c.j deve conter o valor 0xCCCCCCCC, então deve imprimir o valor “-858993460”
  3. c.j pode conter qualquer lixo contido na memória, então não podemos prever qual a saída desse programa

A resposta 1 é escolhida por gente que veio do Java e está aprendendo C++ agora. Ela está errada porque o código gerado para a instanciação de objetos não faz a inicialização de campos primitivos.
A resposta 2 é escolhida por gente que só debuga o programa em modo Debug e nunca rodou o programa compilado em modo Release. Em modo Debug, muitos compiladores, para garantir que o programa sempre rode “deterministicamente” (para poder facilitar a depuração), completam os campos com um valor fixo e que é difícil de ocorrer em um modo normal de execução.
A resposta 3 é a correta. [/quote]

Pois é, e há casos que se pode escrever até em área de memória usada pelo sistema ocasionando a famosa blue screen of death. Não em sistemas modernos a partir do xp, mas de ali para tras um ponteiro mal inicializado(contendo lixo e que pode apontar para qualquer lugar) consegue quebrar o sistema todo com facilidade.