Vector a elementy różnych klas

0

Próbuję zrobić jeden wektor przechowujący obiekty 2 różnych klas, czy jest to możliwe do zrobienia czy będę musiał zrobić to inaczej?
I przy okazji czy to sprawdzanie czy obiekt jest obiektem właśnie tej klasy jest poprawne?

To mój kod:

class KlasaBazowa
{
}

class KlasaPochodna1 : public KlasaBazowa
{
}

class KlasaPochodna2 : public KlasaBazowa
{
}

main()
{
	// std::vector<>Wektor
	
	for (size_t i = 0; i < Wektor.size(); i++)
	{
		//Jakies rozroznienie którą klase obecnie obslugujemy
		
		if (dynamic_cast<KlasaPochodna1*>(Wektor.at(i);) == NULL)
			//...
		else if (dynamic_cast<KlasaPochodna1*>(Wektor.at(i);) == NULL)
			//...

	}
}
3

Bez sensu. Klasa bazowa powinna mieć metodę wirtualną, która jest przeciążona przez obie klasy pochodne. Potem po prostu wywołujesz tę metodę i nie patrzysz na to czym tak naprawdę jest dany obiekt.

3

Po kiego ci to sprawdzanie?
Zrób odpowiednie wirtualne metody i je zwyczajnie wywołuj.

4

Ponad wypowiedź @twonek:

  1. int main() !!!
  2. 2 razy castujesz do tej samej klasy pochodnej. Nawet w tak małym przykładzie udało Ci się pokazać jak łatwo o błędy gdy robisz to źle :)
0
twonek napisał(a):

Bez sensu. Klasa bazowa powinna mieć metodę wirtualną, która jest przeciążona przez obie klasy pochodne. Potem po prostu wywołujesz tę metodę i nie patrzysz na to czym tak naprawdę jest dany obiekt.

_13th_Dragon napisał(a):

Po kiego ci to sprawdzanie?
Zrób odpowiednie wirtualne metody i je zwyczajnie wywołuj.

Własnie problem w tym ze chodzi mi o skladowe a nie o metody.
Nie chcialem skladowych umieszczac w klasie bazowej bo z nich nie korzysta i w 1 klasie dziedziczacej potrzebuje innego typu niz w drugiej, druga ma ich więcej etc. i polowa z nich zwyczajnie nie bedzie uzywana wiec po co je dziedziczyc (Przynajmniej tak mi sie wydaje). Nie bylo by problemu gdyby bylo ich 2/3 ale bedzie okolo 10;

Co prawda moglbym pokombinowac jakos wlasnie aby metody zwracaly te wartosci i je tylko przeslonic ale to i tak nie rozwiazuje mojego problemu gdyż zalezy mi wlasnie na trzymaniu tych klas w jednym wektorze.

class KlasaBazowa
{
public:
	virtual ZrobCos() = 0;
}

class KlasaPochodna1 : public KlasaBazowa
{
private:
	std::string Skladowa;
	
public:
	virtual void ZrobCos() { /* Rob cos na skladowej ... */ }
}

class KlasaPochodna2 : public KlasaBazowa
{
private:
	int Skladowa;
	
public:
	virtual void ZrobCos() { /* Rob cos na skladowej ... */ }
}

main()
{
	// Tu i tak musze jakos trzymac obiekty 2 roznych klas
	// std::vector<>Wektor
	
	for (size_t i = 0; i < Wektor.size(); i++)
	{
		Wektor.at(i).ZrobCos();
	}
}

Wiem ze napisane dosyc chaotycznie ale nie potrafie opisac prosciej o co mi chodzi :D

kq napisał(a):

Ponad wypowiedź @twonek:

  1. int main() !!!
  2. 2 razy castujesz do tej samej klasy pochodnej. Nawet w tak małym przykładzie udało Ci się pokazać jak łatwo o błędy gdy robisz to źle :)

Zauważyłem to dopiero jak zatwierdziłem temat :D

0

Może wtedy:

class KlasaBazowa
  {
   public:
   virtual ZrobCos()=0;
  };
 
template<typename T> class KlasaPochodna1:public KlasaBazowa
  {
   private:
   T Skladowa;
   public:
   virtual void ZrobCos() { /* Rob cos na skladowej ... */ }
   std::string to_string()const { return to_string(Skladowa); }
   void from_string(std::string &value) { istringstream ss(value); ss>>Skladowa; }
  };
0
_13th_Dragon napisał(a):

Może wtedy:

class KlasaBazowa
  {
   public:
   virtual ZrobCos()=0;
  };
 
template<typename T> class KlasaPochodna1:public KlasaBazowa
  {
   private:
   T Skladowa;
   public:
   virtual void ZrobCos() { /* Rob cos na skladowej ... */ }
   std::string to_string()const { return to_string(Skladowa); }
   void from_string(std::string &value) { istringstream ss(value); ss>>Skladowa; }
  };

To niestety nie wchodzi w gre, tych skladowych jest wiecej i maja rozne typy, chyba bede musial to zrobic uzywajac dwoch vectorow :/

0

W takim razie musisz przemyśleć na poważnie strukturę swojego programu. Szkoda, że podałeś mało informacji o tym, w jaki sposób i przez co będą odbierane te dane różnego typu. To ma istotne znaczenie, bo, jeżeli przyjmiemy taki scenariusz, że dane (jak założyłeś prywatne) interesują konkretny obiekt to możesz przypadki "odbioru" zrealizować wewnątrz tych klas przekazując ten obiekt. Mały przykład: https://ideone.com/V32K5J

#include <iostream>
#include <vector>
#include <memory>
 
using namespace std;
 
class Receiver
{
public:
	virtual ~Receiver() = default;
 
	virtual void receiveDataA(int intData, float floatData) = 0;
	virtual void receiveDataB(string stringData, double doubleData) = 0;
};
 
class BaseData
{
public:
    using Ptr = unique_ptr<BaseData>;
 
    virtual ~BaseData() = default;
 
    virtual void receiver(Receiver& receiver) = 0;
};
 
class DataA : public BaseData
{
public:
    DataA(int intData, float floatData) : mIntData{intData}, mFloatData{floatData} {}
 
    void receiver(Receiver& receiver) override
    {
		receiver.receiveDataA(mIntData, mFloatData);
    }
 
private:
    int mIntData;
    float mFloatData;
};
 
class DataB : public BaseData
{
public:
    DataB(string stringData, double doubleData) : mStringData{stringData}, mDoubleData{doubleData} {}
 
    void receiver(Receiver& receiver) override
    {
		receiver.receiveDataB(mStringData, mDoubleData);
    }
 
private:
    string mStringData;
    double mDoubleData;
};
 
struct Object : public Receiver
{
    void receive(BaseData& data)
    {
		data.receiver(*this);
    }
 
    void receiveDataA(int intData, float floatData) override
    {
		cout << "receiveDataA[" << intData << ',' << floatData << "]\n";
    }
 
    void receiveDataB(string stringData, double doubleData) override
    {
		cout << "receiveDataB[" << stringData << ',' << doubleData << "]\n";
    }
};
 
int main()
{
    vector<BaseData::Ptr> mData;
    mData.push_back(make_unique<DataA>(100, 1.));
    mData.push_back(make_unique<DataB>("Hello", 2.f));
    mData.push_back(make_unique<DataB>("World!", 150.f));
    mData.push_back(make_unique<DataA>(200, 50.));
 
    Object object;
 
    for (auto& data : mData)
    {
		object.receive(*data);
    }
 
    return 0;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1