Dúvida em polimorfismo no c++

2 views
Skip to first unread message

Rafael Sales

unread,
Oct 22, 2009, 3:16:24 PM10/22/09
to CPP Brasil - Lista
Pessoal,
Basicamente o problema é que estou querendo passar um objeto especializado por parametro para um construtor que recebe um objeto de uma classe mais abstrata e não estou sabendo guarda-lo em um atributo de forma que consiga utilizá-lo polimorficamente posteriormente.

Criei um exemplo para facilitar: http://paste.ubuntu.com/299263/
Neste programa, sai no console 2 e 0. A saída esperada era 2 e 2.
Já procurei aqui na lista e na internet e não achei exemplo que não utilizasse ponteiro. :/

Obrigado!
Rafael Sales

Rodrigo (skhaz)

unread,
Oct 22, 2009, 3:19:12 PM10/22/09
to ccppb...@googlegroups.com

Rafael Sales

unread,
Oct 22, 2009, 3:31:56 PM10/22/09
to ccppb...@googlegroups.com
Consegui!
Mudei o atributo de
private:
    IFuncao funcao;
para
private:
    IFuncao& funcao;

e no construtor mudei de:
    Teste(IFuncao& pFuncao) {
        this->funcao = pFuncao;
        cout << pFuncao.f(1) << endl;
        cout << this->funcao.f(1) << endl;
    }
para:
    Teste(IFuncao& pFuncao) : funcao(pFuncao) {
        cout << pFuncao.f(1) << endl;
        cout << this->funcao.f(1) << endl;
    }
 
Rodrigo,
Estou ansioso para mexer no Boost - já ouvi falar muito dele - o prof. quer que utilizemos o mínimo de bibliotecas e, como vai ter que ser apresentado, vou ter que explicar o que eu utilizar do Boost para a turma e para o professor.

Valeu!
Rafael Sales


2009/10/22 Rodrigo (skhaz) <rodrigo...@gmail.com>

Thiago Adams

unread,
Oct 22, 2009, 3:56:30 PM10/22/09
to ccppbrasil
Olá,

Objetos polimórficos têm que serem armazenados com ponteiros ou
referências.
Em algumas linguagens todo objeto é uma referência, mas _não_ é o caso
do C++.

Ex:

A b;
A a;
a = b;

a é uma cópia de b.

B b;
A a;

a = b;

Se A é a base de B então neste caso ocorre o "fatiamento" de b para
entrar em um tipo A. Além disso, o polimorfismo é perdido.


A solução é fazer:

B b;
A * a = &b;

ou

B b;
A & a = b;

agora a não é uma cópia mas sim uma referencia para b, ou um endereço
de um objeto b (ponteiro);

A decisão entre usar ponteiro e referência vai passar pelo
entendimento do tempo de vida de b e o tempo de vida de a.
Se b sempre durar mais tempo que a , e a não precisar representar o
estado "referência para nada" então pode-se usar referência.

No caso de ponteiros, b também não pode durar mais que a. No entanto
pode-se fazer a troca de dono. Ou seja, a troca do responsável por
gerenciar b; Neste caso pode ser usados smart pointers ou gerenciar na
mao.


Ex: (na mao)

lass Teste {

IFuncao* funcao;
public:
Teste(IFuncao* p) {
this->funcao = pFuncao;
}
~Teste() { delete funcao; }
};

Neste seu exemplo se você garantir que o objeto passado por referencia
no construtor durar mais que a classe Teste então voce pode usar
referencia.
No caso do ponteiro você ainda tem que definir (e documentar no ctor)
se Teste fica dono do recurso ou não.
No caso da funcao ser deletada em Teste , também é preciso que o
destructor seja virtual.
Também é preciso saber se o objeto precisa ser compartilhado ou
não. :-/

Infelizmente C++ é uma linguagem cheia de detalhes, mas por outro lado
dá total controle sobre que você quer fazer.
Se você quer trabalhar sem considerar os detalhes, pode usar um
shared_ptr.


E. Tadeu

unread,
Oct 22, 2009, 3:25:07 PM10/22/09
to ccppb...@googlegroups.com
Rafael, você não pode guardar o objeto por valor na sua classe... você pode guardar como ponteiro, referência, const-ref ou smart pointer, mas não o objeto inteiro por valor como você fez ;)

   []'s

2009/10/22 Rafael Sales <rafa...@gmail.com>

Rafael Sales

unread,
Oct 22, 2009, 4:45:57 PM10/22/09
to ccppb...@googlegroups.com
Massa!
Entendi o que disseram.

Thiago,
Sou newbie em c++ (logo se vê ;p)... quem veio do Java sofre com essas coisas... obrigado por explicar detalhadamente - não tinha achado na internet sobre isso...
Inclusive gostaria de saber se tem algum livro/site que, durante o aprendizado de C++, já apresenta estes problemas e soluções, pois todos os que vi até hoje usam os velhos &, * e delete e, quando vai ver na prática, os profissionais usam libs para gerenciar ponteiros, memória, ou utilizam práticas que não se vê nesses livros. Pode parecer que essa é uma crítica, mas não é: com essas linguagens de hoje tipo C#, Java, ... o que se encontra nos livros básicos é o que os programadores avançados também usam justamente porque a plataforma de suporte da linguagem já faz tudo...

Muito obrigado.
Rafael Sales


2009/10/22 E. Tadeu <e.t...@gmail.com>

Blabos de Blebe

unread,
Oct 23, 2009, 6:17:20 AM10/23/09
to ccppb...@googlegroups.com
Antes do avançado, vc precisa dominar o básico. Polimorfismo é um tópico básico.

Se você acha que vai encontrar algum framework que te livre de
entender o que é &, * e delete, bom, pode até encontrar, mas
provavelmente vai ser pra algum domínio específico.

Note que, não estou dizendo que você não quer entender, só que na
prática, você vai utilizar essas coisas como ferramentas corriqueiras,
prortanto, vc tem que ter isso na ponta da língua.

Você pediu alguns livros. Já houve uma thread na lista sobre livros,
outra sobre IDEs e coisas assim. Uma pesquisada no histórico e vc vai
encontrar, mas eu sempre gosto de citar:

http://www.research.att.com/~bs/3rd.html
http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612
http://www-cs-faculty.stanford.edu/~knuth/taocp.html

Abraços e bons estudos


2009/10/22 Rafael Sales <rafa...@gmail.com>:
Reply all
Reply to author
Forward
0 new messages