Organizacao de um aplicativo em C++ / + duvidas de iniciante

Só para saber, quando você fala em “aqui” está falando de onde?

Universidade Ceuma
São Luis - MA

Fica só a 2600km daqui. :roll:

Sim sim, isso ta longe de ser um problema, a nao ser que vc nao possa viajar nos ou ter medo de aviao.

Sem problemas com avião.

[quote=ViniGodoy]Basicamente a mesma coisa, mas não vejo muito por que ser desse jeito:
Vai ficar assim:

[code]//Teste.h
class Teste {
private:
Teste t;

Teste(){}

void Teste::imprime(){
cout << "Olá" << endl;
}[/code][/quote]

Náo é à toa que este post foi editado 5 vezes - em C++ certas coisas que se fazem em Java tem de ser escritas de forma sutilmente diferente.
Por exemplo,

class Teste {
private:
    Teste t;
...
};

que superficialmente é equivalente ao seguinte código Java:

class Teste {
    private Teste t = new Teste();
...
};

Este código em C só vai compilar se sizeof(Teste) == 0. O que ocorre se sizeof(T) for diferente de 0? Por exemplo,

class Teste {
private: Teste t;
public: int i;
};

Teste x;

Qual será o valor de sizeof (x)?

O código C ++ que é equivalente ao código Java que postei aqui é:

class Teste {
private:
    Teste *t;
...
    ...
};

Faltou escrever o modificador static lá. Ou deixar com ponteiros, como você fez.

ja tentei conseguir entender qual o problema… mas realmente ta complicado…
to brincando um pouquinho com ponteiros e fiz o seguinte teste:

header

[code]class Pointer {
int *valor;
public:
Pointer();
~Pointer();
Pointer(const Pointer&);

void setValor(int);
int getValor() const;

};[/code]

cpp

[code]#include
#include “teste.h”

using namespace std;

Pointer::Pointer(){
valor = new int(0);
}

Pointer::~Pointer(){
cout << "Destruindo o objeto de valor: " << endl;
}

Pointer::Pointer(const Pointer& p){
valor = p.valor;
}

void Pointer::setValor(int value){
valor = &value;
}

int Pointer::getValor() const {
return *valor;
}[/code]

e main

[code]#include
#include “teste.h”

using namespace std;

int main(){

Pointer p;
p.setValor(13);

Pointer p2(p);
cout << p2.getValor() << endl;

p.setValor(12);

cout << p2.getValor() << endl;

return 0;	

}[/code]

saida:

[quote]rafael@rafael-note:~/Área de Trabalho/C/C++$ ./a.out
-1076317336
12
Destruindo o objeto de valor:
Destruindo o objeto de valor:[/quote]

de onde saiu esse: -1076317336

visto que da segunda vez que utilizo o metodo set funciona???
estranho :shock: :shock:

Não não não não não faça isto aqui.

void Pointer::setValor(int value){  
    valor = &value;  
} 

O que é que você fez?
Você pegou um endereço de uma variável no stack (não no heap) e o atribuiu dentro de uma variável de instância de um seu objeto.
Como você deve saber, parâmetros e variáveis locais residem ou no stack, ou então em registradores da CPU, dependendo do grau de otimização do seu compilador.
Você poderia até passar esse endereço para um outro método dentro desse método que você escreveu, porque o tempo de vida é dentro da execução desse método.
Mas desse jeito que você fez, o programa saiu do método setValor e ficou com um endereço que aponta para uma área que você não tem mais posse.

Nunca faça isso. Nunca nunca nunca. Você vai tomar na cabeça até entender o que estou falando.

[quote=entanglement]Não não não não não faça isto aqui.

void Pointer::setValor(int value){  
    valor = &value;  
} 

O que é que você fez?
Você pegou um endereço de uma variável no stack (não no heap) e o atribuiu dentro de uma variável de instância de um seu objeto.
Como você deve saber, parâmetros e variáveis locais residem ou no stack, ou então em registradores da CPU, dependendo do grau de otimização do seu compilador.
Você poderia até passar esse endereço para um outro método dentro desse método que você escreveu, porque o tempo de vida é dentro da execução desse método.
Mas desse jeito que você fez, o programa saiu do método setValor e ficou com um endereço que aponta para uma área que você não tem mais posse.

Nunca faça isso. Nunca nunca nunca. Você vai tomar na cabeça até entender o que estou falando.

[/quote]

eu vinha qui justamente postar isso… mas nao to entendendo… pq funcionou com o valor 12 oO’
visto que a variavel morre no final…

Bem vindo a Hogwarts - mais conhecido como “mundo da programação em C++”.

De fato, você pode ter esse tipo de comportamento - algo que aparentemente está certo, mas que na verdade está acessando memória indevidamente.

Como eu disse, é o tipo de coisa que é fácil de fazer mas que é muito difícil de corrigir. Muitas vezes você precisa ter o conhecimento da Hermione e a sorte do Harry Potter para descobrir certos problemas - é claro que existem várias ferramentas que permitem descobrir esses problemas, mas na prática nem sempre você tem o tempo ou o dinheiro para poder rodar as ferramentas e descobrir os problemas.

olha isso:

[code] Pointer p;
p.setValor(13);

Pointer p2(p);
cout << p2.getValor() << endl;

p.setValor(12);
cout << p2.getValor() << endl;
cout << p2.getValor() << endl;
cout << p2.getValor() << endl;

[/code]

resultado:

rafael@rafael-note:~/Área de Trabalho/C/C++$ ./a.out Criando um objeto -1081173672 12 134514112 134514112

é como se a variavel ainda estivesse no stack… o metodo de impressão foi mais rapido… (ou estou viajando?)

Cuidado… seu construtor de cópia está copiando o ponteiro, não o valor do ponteiro.

O certo seria:

Pointer::Pointer(const Pointer& p){ valor = new int(); *valor = *(p.valor); }

O setValor também está errado. Você quer alterar o valor que está no local onde o ponteiro aponta, para uma cópia do valor que veio por parâmetro:

void Pointer::setValor(int value){ *valor = value; }

Por fim, falou dar delete valor no seu destrutor.

A variável ainda está no stack, mas pode ser que alguma outra atividade acabe “estragando” esse valor que está no stack (e é por isso que você tem esses resultados bizarros).

Experimente recompilar seu código com outro compilador, e veja que os resultados serão diferentes.

Construtores de cópia podem copiar ponteiros se eles mantiverem uma contagem de referências, o que está fora do escopo para você que está ainda aprendendo a dar tiros no pé com C++ :slight_smile:
Normalmente você deve fazer uma cópia da coisa apontada, como indicou o Vinicius Godoy.

Considero o uso “cru” de ponteiros como o “goto” e as threads do Java - se você não souber o que está fazendo, pode fazer um monte de besteiras (como aquele policial que matou o colega dele que estava em uma motocicleta e fingiu que era um bandido).

Se souber, ainda vai fazer besteiras de vez em quando :slight_smile:

É o “zen” da programação - você aprende a usar ponteiros, apenas para poder saber que não deve usá-los sem proteção adequada. É para dar um monte de tiros no pé para aprender mesmo :slight_smile:

na verdade… eu fiz desse jeito de proposito mesmo… so esqueci que a variavel passada por parametro iria morrer ao fim do metodo…
mas a ideia mesmo era modificar uma variavel de um objeto através de outro…

mas pessoal… aprecio muito a ajuda de vcs…
obrigado a todos :smiley:

Eu sempre digo que um bom programador C++ sabe usar ponteiros. E um programador C++ excelente sabe não usa-los.