Ir ao conteúdo
  • Cadastre-se

C++ - polimorfismo e static


Cambalinho

Posts recomendados

eu entendi que polimorfismo é 1 class derivada de outra(mas para fazermos sobrecarga, as funçoes tem de ser virtuais):

class base
{
string name;
public:
virtual void show()
{
show();
}
string Name()
{
return name;
}
void Name(string value)
{
name=value;
show();
}
};

a minha questao é a seguinte:

na nova class:

class test: public base
{
static void show()//aqui da-me erro
{
cout << "name changed";
}

};

como posso transformar as funçoes de tal forma em eu possa usar a class test static?

Link para o comentário
Compartilhar em outros sites

voce não pode sobreescrever um metodo com o modificador static.

static é quando você não precisa de uma instancia da classe para chamar.

e neste caso queria fazer com que a class test fosse static. para nao fazer 1 instancia da class.

ainda tenho 1 duvida: se podemos fazer polimorfismo com as classes, porque não podemos fazer isso com instancias da class?

Link para o comentário
Compartilhar em outros sites

e neste caso queria fazer com que a class test fosse static. para nao fazer 1 instancia da class.

ainda tenho 1 duvida: se podemos fazer polimorfismo com as classes, porque não podemos fazer isso com instancias da class?

Tente entender esse codigo

#include <iostream>
#include <list>

using namespace std;

class Funcionario
{
private:
double salario;
public:
Funcionario(double salario)
{
this->salario = salario;
}

virtual double getSalario()
{
return salario;
}

virtual void setSalario(double salario)
{
this->salario = salario;
}

virtual void darAumento()
{
setSalario(getSalario() * 1.1);
}
};

class Gerente : public Funcionario
{
public:
Gerente(double salario) : Funcionario(salario)
{
}

void darAumento()
{
setSalario(getSalario() * 1.5);
}
};

class FolhadePagamento
{
public:
list<Funcionario*> *funcionarios;
FolhadePagamento()
{
funcionarios = new list<Funcionario*>();
}

void darAumento()
{
for (auto i = funcionarios->begin(); i != funcionarios->end(); i++)
{
(*i)->darAumento();
}
}
};

int main()
{
Funcionario *f = new Funcionario(1000.0);
Funcionario *g = new Gerente(1000.0);
FolhadePagamento fp;
fp.funcionarios->push_back(f);
fp.funcionarios->push_back(g);

cout << f->getSalario() << endl;
cout << g->getSalario() << endl;

fp.darAumento();

cout << f->getSalario() << endl;
cout << g->getSalario() << endl;

getchar();
return 0;
}

Link para o comentário
Compartilhar em outros sites

Tente entender esse codigo

#include <iostream>
#include <list>

using namespace std;

class Funcionario
{
private:
double salario;
public:
Funcionario(double salario)
{
this->salario = salario;
}

virtual double getSalario()
{
return salario;
}

virtual void setSalario(double salario)
{
this->salario = salario;
}

virtual void darAumento()
{
setSalario(getSalario() * 1.1);
}
};

class Gerente : public Funcionario
{
public:
Gerente(double salario) : Funcionario(salario)
{
}

void darAumento()
{
setSalario(getSalario() * 1.5);
}
};

class FolhadePagamento
{
public:
list<Funcionario*> *funcionarios;
FolhadePagamento()
{
funcionarios = new list<Funcionario*>();
}

void darAumento()
{
for (auto i = funcionarios->begin(); i != funcionarios->end(); i++)
{
(*i)->darAumento();
}
}
};

int main()
{
Funcionario *f = new Funcionario(1000.0);
Funcionario *g = new Gerente(1000.0);
FolhadePagamento fp;
fp.funcionarios->push_back(f);
fp.funcionarios->push_back(g);

cout << f->getSalario() << endl;
cout << g->getSalario() << endl;

fp.darAumento();

cout << f->getSalario() << endl;
cout << g->getSalario() << endl;

getchar();
return 0;
}

eu tive esta idea com o teu codigo:

class test: public base
{
static void hello(): show()//erro
{
cout << "Name Changed";
}
};

mas eu recebo 1 erro:

"C:\Users\Joaquim\Documents\CodeBlocks\test2\main.cpp|27|error: only constructors take member initializers|"

nao entendo o porque do erro:(

Link para o comentário
Compartilhar em outros sites

Não é possivel fazer isso com static. Não insista. Não faz sentido nenhum fazer isso. Se quiser ter um metodo static crieo com outro nome.

e ja me apercebi que me enganei:(

class base
{
string name;
public:
virtual void show()
{
show();
}
string Name()
{
return name;
}
void Name(string value)
{
name=value;
show();
}
};

class test: public base
{
void show()
{
cout << "name changed";
}
};

class test1: public base
{
void show()
{
cout << "name2 changed";
}

};

int main()
{
test a;
string b;
getline(cin, ;
a.Name(;
getch();//conio.h
}

este codigo funciona. mas penso que posso resolver isto, mas sou muito novo nos Templates.

1 pergunta: posso transformar o 'test' e a 'a' numa Template?

o que pretendo: em vez de 1 class, usar a variavel para poder alterar as funçoes virtuais. porque estou a ver que tenho de criar 1 class diferente para cada variavel:(

podes me dar algumas dicas?

Link para o comentário
Compartilhar em outros sites

Me diga qual o problema. Não estou entendendo o que quer fazer.

'eventos' em C++(entre aspas, porque sei que o C++ nao tem eventos)

mas pensa desta forma: tenho 1 class que chama 1 funçao(mas dá 1 resultado diferente dependendo das propriedades\membros do objecto). por isso é que mostrei aquele exemplo: mas para cada objecto tenho de fazer 1 nova class(derivada da 'base'):(

existe outra forma de resolver esta situaçao?

desculpa o meu portugues.

mas ja vistes que tenho sempre de fazer 1 subclass para cada objecto?

(ao usar 1 funçao virtual, ja posso a sobreescrever com a 1 subclass)

mas ve isto:

class test:public classbase
{
void show()
{
cout << "ola test";
}
};


class test1:public classbase
{
void show()
{
cout << "ola test1";
}
};


main()
{
test a;
test1 b;
a.setname("joaquim");//a funçao show() é chamada após alterar o nome
b.setname("joana");

getch();//conio.h
}

como ves, por cada funçao show diferente, eu tenho de criar 1 class derivada da class base. a minha questao é a seguinte: imagina que temos mais do que 5 funçoes virtuais e que temos mais do que 5 objectos. é muito trabalhoso criar mais de 5 classes(como mais de 5 funçoes virtuais) diferentes.

eu sou muito novo com templates, mas acredito que os templates podes resolver o meu problema. mas preciso de ajuda para fazer este tipo de templates:(

ou seja: o templates criava a class e o objecto e assim faziamos:

void classnome::funçaovirtual()
{
//faz qualquer coisa
}

se calhar vou ter de fazer por passos;)

olha como, em tamplates, faço 1 argumento para receber 1 funçao(mesmo com argumentos)?

Link para o comentário
Compartilhar em outros sites

Como já falei pra você em um outro topico, você esta tentando transformar o C++ em C#/VB.net.

O c++ tem ponteiro de função que é usado para criar evento.

#include <iostream>
#include <string>

using namespace std;

class Pessoa
{
private:
string nome;
public:
void(*onSetNome)(string, string);

Pessoa(string nome)
{
this->nome = nome;
}

void setNome(string nome)
{
onSetNome(this->nome, nome);
this->nome = nome;
}

string getNome()
{
return nome;
}
};

void MostrarNomeAntigoeNovo(string antigo, string novo)
{
cout << "Nome " << antigo << " alterado para " << novo;
}

int main()
{
Pessoa p("Joao");
p.onSetNome = MostrarNomeAntigoeNovo;

p.setNome("Jose");

getchar();
return 0;
}

No exemplo acima, quando chamamos temos um evento que é chamado sempre que chamamos o metodo setNome, neste caso coloquei para chamar o metodo MostrarNomeAntigoeNovo, mas você pode chamar o metodo que você quiser, desde que siga a assinatura void(*onSetNome)(string, string);

Link para o comentário
Compartilhar em outros sites

Como já falei pra você em um outro topico, você esta tentando transformar o C++ em C#/VB.net.

O c++ tem ponteiro de função que é usado para criar evento.

#include <iostream>
#include <string>

using namespace std;

class Pessoa
{
private:
string nome;
public:
void(*onSetNome)(string, string);

Pessoa(string nome)
{
this->nome = nome;
}

void setNome(string nome)
{
onSetNome(this->nome, nome);
this->nome = nome;
}

string getNome()
{
return nome;
}
};

void MostrarNomeAntigoeNovo(string antigo, string novo)
{
cout << "Nome " << antigo << " alterado para " << novo;
}

int main()
{
Pessoa p("Joao");
p.onSetNome = MostrarNomeAntigoeNovo;

p.setNome("Jose");

getchar();
return 0;
}

No exemplo acima, quando chamamos temos um evento que é chamado sempre que chamamos o metodo setNome, neste caso coloquei para chamar o metodo MostrarNomeAntigoeNovo, mas você pode chamar o metodo que você quiser, desde que siga a assinatura void(*onSetNome)(string, string);

obrigado, mas deixa-me perguntar 1 coisa:

void Pessoa::MostrarNomeAntigoeNovo(string antigo, string novo)
{
cout << "Nome " << antigo << " alterado para " << novo;
}

esta funçao nao difere dos objectos:(

(e sim... a funçao é alterado fora da class, como eu preciso)

como a posso fazer diferenciar dos objectos\instancias?

Link para o comentário
Compartilhar em outros sites


void MostrarNomeAntigoeNovo(string antigo, string novo)
{
cout << "Nome " << antigo << " alterado para " << novo;
}

void NaoMostrarNada(string antigo, string novo)
{
cout << "&&&&&&&";
}

int main()
{
Pessoa p("Joao");
p.onSetNome = MostrarNomeAntigoeNovo;
p.setNome("Jose");

Pessoa p("A");
p.onSetNome = NaoMostrarNada;
p.setNome("B");

getchar();
return 0;
}

Não é isso que você quer?

Se quer alterar o que a função faz com herança, use o modificador virtual na base e sobreescreva o metodo na outra, mas o modificador não pode ser static.

Link para o comentário
Compartilhar em outros sites


void MostrarNomeAntigoeNovo(string antigo, string novo)
{
cout << "Nome " << antigo << " alterado para " << novo;
}

void NaoMostrarNada(string antigo, string novo)
{
cout << "&&&&&&&";
}

int main()
{
Pessoa p("Joao");
p.onSetNome = MostrarNomeAntigoeNovo;
p.setNome("Jose");

Pessoa p("A");
p.onSetNome = NaoMostrarNada;
p.setNome("B");

getchar();
return 0;
}

Não é isso que você quer?

Se quer alterar o que a função faz com herança, use o modificador virtual na base e sobreescreva o metodo na outra, mas o modificador não pode ser static.

agora entendi.... muito obrigado amigo;)

estou a ver que posso transformar(se quiser) a setNome() em static;)

1 pergunta: posso declarar estas funçoes(NaoMostrarNada e MostrarNomeAntigoeNovo) no construtor?

Link para o comentário
Compartilhar em outros sites

	Pessoa(string nome, void(*onSetNome)(string, string))
{
this->nome = nome;
this->onSetNome = onSetNome;
}

esse construtor?

você NÃO pode transformar uma função não static em static.

qual apostila esta seguindo para aprender OO?

Teach YourSelf C++ one hour a day... mas aceito sugestoes;)

Link para o comentário
Compartilhar em outros sites

aprendi OO com a apostila da Caelum de Java(mas usava C# :D), tambêm tem a da K19 em C#. Mas de C++ não conheço.

mas sou-te sincero, nao foi fácil aprender o que é polimorfismo lol

falando de compiladores(e nao versões)... porque existem varias formas de C++?

(GNU compiler\ microsoft e outros)

Link para o comentário
Compartilhar em outros sites

usando C++ Ansi não terá problemas, mas infelizmente essa padronização não tem GUI (e provavelmente nunca terá) e network.

yah no Visual C++(projecto consola) fazes 1 propriedade com 1 linha de codigo juntando as 2 funçoes principais(muito fixe\legal), mas nao é ANSI(American National Standard Institute):(

(e os eventos tambem :()

por isso estou a usar o Code Blocks. porque estou a usar o compilador GNU e que vou precisar para a minha linguagem(sabes que é muito complexo fazer 1 compilador... por isso faço o meu conversor e os erros, claro, tem de estar compativeis com a minha linguagem;)).

olha estou a alterar 1 pouquinho o teu codigo;)

o que fiz foi a forma como dar o nome ás funçoes;)

nomedoobjecto_nomedafunçao()

exemplo:

#include <iostream>
#include <conio.h>

using namespace std;

class Pessoa
{
private:
string nome;
public:
void(*onSetNome)(string, string);
Pessoa(string nome,void(*onSetNome)(string, string))
{
this->nome = nome;
this->onSetNome = onSetNome;
}

void setNome(string nome)
{
onSetNome(this->nome, nome);
this->nome = nome;
}

string getNome()
{
return nome;
}
};

void p_MostrarNomeAntigoeNovo(string antigo, string novo)
{
cout << "Nome " << antigo << " alterado para " << novo;
}

void vasco_MostrarNomeAntigoeNovo(string antigo, string novo)
{
cout << "Nome " << antigo << " alterado para " << novo;
}

int main()
{
Pessoa p("Joao",p_MostrarNomeAntigoeNovo);

p.setNome("Jose");
Pessoa vasco("joaquim",vasco_MostrarNomeAntigoeNovo);
vasco.setNome("ana");

getchar();
return 0;
}

é 1 forma mais simples para nao esquecer de quem é a funçao;)

Link para o comentário
Compartilhar em outros sites

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...