• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Vector wskaźników do klasy abstrakcyjnej.

Object Storage Arubacloud
0 głosów
2,104 wizyt
pytanie zadane 21 maja 2015 w C i C++ przez Ins0mniaC Obywatel (1,400 p.)
otwarte ponownie 23 maja 2015 przez Ins0mniaC

Witam. Mam klasę abstrakcyjną i dwie po niej dziedziczące. Teraz chcę stworzyć vector wskaźników klasy abstrakcyjnej (Zwierz) i wypełnić ją normalnymi (Psami i Kotami). Nie mam za bardzo jednak pomysłu jak to zrobić, mam jakieś herezje w main jeśli ktoś tylko spojrzy. 

Main:

#include <iostream>
#include <vector>
#include <string>
#include <time.h>
#include <algorithm> 
#include "Zwierz.h"
#include "Pies.h"
#include "Kot.h"

using namespace std;

void f_glos(Zwierz &f)
{
	f.daj_glos();
}

void f_roczek(Zwierz &f)
{
	f.rok_urodzenia();
}

void f_imi(Zwierz &f)
{
	f.imie();
}

int main()
{
	srand(time(NULL));
	vector<Zwierz> *zwierzoki;
	Kot k1;
	Kot k2;
	Kot k3;
	Pies p1;
	Pies p2;
	Pies p3;
	zwierzoki->push_back(k1);
	zwierzoki->push_back(k2);
	zwierzoki->push_back(k3);
	zwierzoki->push_back(p1);
	zwierzoki->push_back(p2);
	zwierzoki->push_back(p3);
	f_glos(k1);
	f_glos(p2);
	f_roczek(k1);
	f_roczek(p2);
	f_imi(k1);
	f_imi(p2);
	system("pause");
	return 0;
}

Zwierz.h

#pragma once

class Zwierz
{
public:
	Zwierz();
	virtual void rok_urodzenia()=0;
	virtual void imie()=0;
	virtual void daj_glos()=0;
	~Zwierz();
};

Zwierz.cpp

#include "Zwierz.h"

Zwierz::Zwierz()
{
}

Zwierz::~Zwierz()
{
}

 

Pies.h

#pragma once
#include "Zwierz.h"
#include <string>
#include <iostream>

using namespace std;

class Pies:public Zwierz
{
public:
	int rok;
	string glos;
	string im;
	Pies();
	void rok_urodzenia();
	void imie();
	void daj_glos();
	~Pies();
};

 

Pies.cpp

#include "Pies.h"
#include "Zwierz.h"
#include <string>
#include <iostream>

Pies::Pies():rok((rand()%15)+2000),glos("WOW"),im("Piesel")
{
}

void Pies::rok_urodzenia()
{
	cout<<"Rok urodzenia tego psa to: "<<rok<<endl;
}

void Pies::imie()
{
	cout<<"Imie tego psa to: "<<im<<endl;
}
void Pies::daj_glos()
{
	cout<<"Ten pies robi: "<<glos<<endl;
}

Pies::~Pies()
{
}

 

Kot.h

#pragma once
#include "Zwierz.h"
#include <string>
#include <iostream>

using namespace std;

class Kot:public Zwierz
{
public:
	int rok;
	string glos;
	string im;
	Kot();
	void rok_urodzenia();
	void imie();
	void daj_glos();
	~Kot();
};

 

Kot.cpp

#include "Kot.h"
#include "Zwierz.h"
#include <string>
#include <iostream>

Kot::Kot():rok((rand()%15)+2000),glos("MRR"),im("Kotel")
{
}

void Kot::rok_urodzenia()
{
	cout<<"Rok urodzenia tego kota to: "<<rok<<endl;
}

void Kot::imie()
{
	cout<<"Imie tego kota to: "<<im<<endl;
}
void Kot::daj_glos()
{
	cout<<"Ten Kot robi: "<<glos<<endl;
}

Kot::~Kot()
{
}

 

3 odpowiedzi

+1 głos
odpowiedź 21 maja 2015 przez Radfler VIP (101,030 p.)
wybrane 21 maja 2015 przez Ins0mniaC
 
Najlepsza

Mała poprawka: w main() zrobiłeś wskaźnik do std::vector, pownieneś zrobić tak:

std::vector<Zwierz*> zwierzoki;

I masz std::vector wskaźników na klasę Zwierz :)

A potem wypełnij ją push_backiem tak:

Kot k1;
zwierzoki.push_back(&k1); // dodajesz adres

A pracujesz tak:

zwierzoki[0]->imie(); // wywołenie wirtualnej funkcji imie

Poczytaj też sobie dokumentację: http://en.cppreference.com/w/cpp/container/vector

Voila! :D

EDIT:

Kolega niżej wspomniał o takim zapisie:

zwierzoki.push_back(new Pies);

Nigdy tak nie rób, gdyż zostanie utworzony dynamiczny obiekt pies, który po usunięciu std::vector zostanie nieusunięty - dojdzie do wycieku pamięci. A jak Ci zależy na takim zapisie to użyj funkcji std::vector::emplace http://en.cppreference.com/w/cpp/container/vector/emplace, która tworzy obiekt :)

+1 głos
odpowiedź 21 maja 2015 przez Sebastian Fojcik Nałogowiec (43,040 p.)
edycja 21 maja 2015 przez Sebastian Fojcik

Tworząc wektor:

std::Vector< typ_do_przechowania> nazwa_wektora

W takim razie, nie widzę problemu, aby zrobić wektor wskaźników na klasę abstrakcyjną:

vector<Zwierz*> zwierzoki;

Dopóki nie tworzymy obiektu na podstawie klasy abstrakcyjnej, możemy spać spokojnie :)
Pamiętaj aby "wpychać" do wektora wskaźniki (lub adresy &) a nie same obiekty.
 

Pies reksio;
zwierzoki.push_back( &reksio );

Jest jeszcze taki cud, uwaga uwaga:

zwierzoki.push_back( new Pies );

Możemy to zrobić pod warunkiem, że klasa "Pies" posiada konstruktor domyślny. Zapis taki zadziała, bo operator "new" zwraca adres obiektu, który tworzy.

Dzięki temu nie tworzymy obiektu "reksio" lokalnego, tylko dynamicznie. Jest to bardzo ważne, bo po opuszczeniu funkcji pamięć jest zwalniana. U ciebie jest main(), ale gdyby to była inna funkcja, to po jej opuszczeniu w wektorze byłby adres, który może do Ciebie już nie należeć. Jeśli więc możemy, to przesyłajmy adresy obiektów dynamicznie utworzonych. One nigdy nie znikają bez naszej wiedzy.

Pozdrawiam :)

0 głosów
odpowiedź 21 maja 2015 przez Ins0mniaC Obywatel (1,400 p.)
Dziękuję bardzo za odpowiedź, dodałbym również jedno pytanie- w jaki sposób mam posortować ten vector, załóżmy względem daty urodzenia?

Podobne pytania

0 głosów
1 odpowiedź 665 wizyt
0 głosów
1 odpowiedź 445 wizyt
0 głosów
1 odpowiedź 245 wizyt

92,580 zapytań

141,432 odpowiedzi

319,665 komentarzy

61,965 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...