Atributo genérico no C++

Pessoal alguém sabe se tem alguma forma de criar um atributo genérico no C++?, tipo um “object”…

Vou tenta ser bem claro…

Criei um método com template, até ai beleza, só que não consegui fazer funcionar template com o atributo da classe, dá um erro e o V.S para de funcionar…

Segue o código…

       private:			
	    vector<int> condicoes;

       public:	
		
		template <class myType>
		myType getValue(int posicao)
		{
			return (myType) this->condicoes.at(posicao);
		};

Preciso de alguma lista que aceite qualquer objeto… Não precisa necessariamente usar o vector…

Qualquer duvida estou a disposição.

Obrigado.

Não entendi o que você quer. O vector aceita qualquer tipo de objeto.

Você pode fazer isso aqui:

private:			
   vector&lt;int&gt; condicoes;

public:		
   int getValue(int posicao)
   {
      return condicoes[i];
   };

Ou então, se quiser deixar tudo genérico:

[code]template <typename T>
public class SuaClasse {
private:
vector<T> valor;

public:
T getValue(int posicao)
{
return condicoes[i];
}
};

//Isso usa assim
SuaClasse suaClasse;
int valor = suaClasse.getValue(1);
[/code]

Outra coisa. Você está trabalhando mesmo com tudo no .h? Ou você só contrai para postar aqui no GUJ?

Outra coisa. Lembre-se que no C++, o vector trabalha por valor. Isso significa que adicionar objetos e retira-los do vector irá chamar o construtor de cópia. Cuidado também que não existe “polimorfismo por valor”.

Uma opção é ter um vector de ponteiros. Outra, ainda melhor, é trabalhar com smart pointers.

Além disso, vale ressaltar que templates e generics são coisas completamente diferentes. Templates são muitíssimo mais poderosos e efetivamente eliminam restrições de tipos de maneira typesafe. Generics já servem para reforçar o sistema de tipos. Não trate os dois como se fossem a mesma coisa.

Estou usando tudo no .h mesmo(somente para essa classe referencia http://www.linhadecodigo.com.br/artigo/1672/B%C3%A1sico-de-C-Templates.aspx), pq como estou usando templates o compilador não consegue compilar, ele da um erro de link, pois estou montando uma espécie de “biblioteca”.

A forma de como queria o vetor ou lista seria assim…


private:              
   vector<Object> condicoes; //Assim não funciona, mas é forma como consegui expressar.....

Logo esse atributo condições aceitaria qualquer tipo, int, string, char e etc…

Não quero usar o template em toda a classe pois uma vez que a classe for instanciada, a lista pode aceitar qualquer tipo…

Entendeu o problema?

Desculpe ter misturado generic com template…

O C++ não tem um “tipo objeto” (ou seja, pai de todas as classes) como o Java. Pensar em Java nem sempre é muito adequado em C++.

Então fica difícil você ter um “vetor de objetos” tal como há um “ArrayList”.

Se você usar o boost, pode usar o tipo boost::variant que se comporta como um tipo que pode comportar vários tipos de objetos.

boost::variant: http://beta.boost.org/doc/libs/1_44_0/doc/html/variant.html

Ele é o mais parecido possível com um Object que você pode ter em C++.

Ainda assim, mesmo em java, um vector<object> é uma péssima alternativa de projeto. Exige casts, é difícil de trabalhar.

O que exatamente você quer fazer? Talvez seja interessante criar sua própria abstract base class.

Sim, no caso de templates é obrigatório colocar .h e .cpp no mesmo arquivo. Perguntei pq vc já passou outros exemplos aqui com tudo junto, e esse é um erro relativamente comum de quem do Java vai pro C++ e sai programando.

Bem eu programo tudo separado, .h e .cpp esse foi o único que fiz assim(pq ele me obriga)…

Bem estou montando uma classe para conectar no oracle, a biblioteca occi da oracle não funciona nem com “reza braba”(lembra postei até alguns post sobre isso), então achei uma biblioteca chamada OTL, ela usa a OCI da própria oracle mesmo, essa funcionou muito bem, no primeiro teste que fiz funcionou, no entanto ela não é muito funcional, então estou montando uma classe que conecta,executa a consulta e retorna os dados para outra classe, +/- como o Statement e o ResultSet no caso do java, esse trabalho tem o intuito de facilitar o trabalho de acesso a dados…

Enfim e é por isso que esta precisando de uma lista de objetos de que aceite qualquer estrutura…

As vezes vocês podem pensar em outra idéia melhor, estou aberto a sugestões…

Obrigado…

Então não é “qualquer coisa”.
É um dos tipos que podem ser tipos de colunas em uma tabela: numérico, string etc.
O boost::variant, no seu caso, deve cair como uma luva.
Embora o exemplo na página que lhe passei faça um variant que aceita apenas 2 tipos (int & string), é possível passar até 20 tipos diferentes, o que é mais que suficiente para todos os tipos que podem ser retornados pelo Oracle (espero))

// Exemplo de programação com boost::variant
#include <boost/variant.hpp>
#include <boost/variant/get.hpp>
#include <boost/foreach.hpp>
#include <iostream>
#include <vector>
#include <string>

using namespace boost;
using namespace std;

typedef vector<int> INTVECTOR;
typedef boost::variant<int, double, string, INTVECTOR> MYVARIANT;

int main (int argc, char *argv[]) {
    vector<MYVARIANT> myvs;
    INTVECTOR iv;
    iv.push_back (3); iv.push_back (1); iv.push_back (4); iv.push_back (1); 
    
    myvs.push_back (10);
    myvs.push_back (20.4);
    myvs.push_back (string ("hare hare"));
    myvs.push_back (iv);
    BOOST_FOREACH (MYVARIANT var, myvs) {
        switch (var.which()) {
        case 0: // int
            cout << get<int>(var) << endl;
            break;
        case 1: // double
            cout << get<double>(var) << endl;
            break;
        case 2: // std::string
            cout << get<string>(var) << endl;
            break;
        case 3: // vector<int>
            BOOST_FOREACH (int x, get<INTVECTOR>(var)) {
                cout << x << ", ";
            }
            cout << endl;
            break;
        default:
            break;
        }
    }
}

O BOOST_FOREACH é mais ou menos o equivalente ao foreach do Java . Em uma versão posterior da especificação do C++ (que ainda não foi fechada, chamada C++0X) está previsto ter algo parecido (e até com a mesma sintaxe e significado) do foreach do Java.

Obrigado entanglement por postar o código, achei muito interessante, ainda não conhecia essa estrutura, vou fazer alguns testes com ela.

Obrigado.

entanglement ainda não fiz os testes, estava lendo o código e surgiu uma duvida, o que acontece se eu inserir dessa forma:

    myvs.push_back (10);
    myvs.push_back (20.4);
    myvs.push_back (string ("hare hare"));
    myvs.push_back (string ("repetindo novamente a string"));
    myvs.push_back (iv);

Ele reconhece que é string e insere ou ele pensa que é um vector e da erro?

Reconhece que é string. Isso é porque o tipo foi explicitamente passado, nesse caso.

“Hare hare” pra você também!