Wyrzucanie adresu na strumien wyjscia.

0

Jak w temacie wyrzuca mi adres na strumień wyjścia, kiedy probuje wyświetlić pola obiektów (Nie wiem jak to wytłumaczyć ale wrzucając w kompilator zobaczycie o co mi chodzi). Nie wiem dlaczego tak się dzieję , chciałem po prostu wyświetlić pola klas za pomocą funkcji wirtualnej wypisz i przeładowanego operatora wyjścia.

Jakby ktoś z was, mógłby mi wskazać, gdzie leży błąd byłbym bardzo wdzięczny.

 
#include <iostream>


using namespace std;

class osoba{
protected:
    string* imie;
    string nazwisko;
public:
    osoba():imie(new string("brak ")),nazwisko("brak"){}
    osoba(const string& a1,const string& a2):imie(new string(a1)),nazwisko(a2){}
    osoba(const osoba& ob):imie(new string(*ob.imie)),nazwisko(ob.nazwisko){}
    virtual ostream& wypisz(ostream& out){out << *imie << " " << nazwisko;}
    friend ostream& operator<<(ostream& out,osoba& ob){out << ob.wypisz(out);}
    virtual ~osoba(){delete imie;}
};
class student:public osoba{
    string kierunek;
    unsigned rok;
public:
    student():osoba(){}
    student(const osoba& ob):osoba(ob){}
    student(const osoba& ob,const string& a1,const unsigned& a2):osoba(ob),kierunek(a1),rok(a2){}
    ostream& wypisz(ostream& out){out << *imie << " " << nazwisko << " " << kierunek << " " << rok << endl;}
};
//osoba::ktory = 0;
int main()
{
	const osoba o1("Jan", "Kowalski");
	const osoba o2("Ewa", "Nowak");

	osoba* tab[5];

	tab[0] = new osoba;
	tab[1] = new student;
	tab[2] = new osoba("Ala", "Kot");
	tab[3] = new student(o1);
	tab[4] = new student(o2, "Informatyka",3);

	for(int i = 0; i < 5; i++)
		try
		{
			cout << *tab[i] << endl;
		}
		catch (const string& err)
		{
			cerr << err << endl;
		}

	cout << "**********" << endl;

	return 0;
}

2

Może na początku załącz kod, który się kompiluje?

Bonusik, skoro korzystasz z std::string to zawsze miej

#include <string>

nawet wtedy gdy konkretny kompilator twierdzi, że nie potrzebuje.

I polecam: http://format.krzaq.cc/ (style file)

0

Ten kod co podałem u góry normalnie mi się kompiluje w codeblocku.

user image
http://screenshot.sh/ouZrzVg6cn675

4

Ponad to co napisał @twonek:

virtual ostream& wypisz(ostream& out){out << *imie << " " << nazwisko;}
UB, funkcja nic nie zwraca wbrew deklaracji.

friend ostream& operator<<(ostream& out,osoba& ob){out << ob.wypisz(out);}
Nie jestem pewien jak to się ma do standardowych streamów (@Endrju?) ale śmierdzi mi to dwukrotną niesekwencjonowaną modyfikacją tej samej zmiennej (UB). Oczywiście brak retrurn (expr) to również tutaj UB.

    osoba* tab[5];
 
    tab[0] = new osoba;
    tab[1] = new student;
    tab[2] = new osoba("Ala", "Kot");
    tab[3] = new student(o1);
    tab[4] = new student(o2, "Informatyka",3);

Nie używaj nagich wskaźników do innego celu niż obserwacji. Nagie new i delete (którego, nota bene, brak) to antyidiomy w nowoczesym C++. Polecam std::unique_ptr<osoba>, a tutaj nawet std::vector<std::unique_ptr<osoba>> lub boost::ptr_vector

4

Rzeczywiście w starym C++ się kompiluje: http://ideone.com/qGA55X, co by sugerowało, że istnieje coś w stylu (wtf?)

operator<<(ostream&, const ostream&)

Natomiast kompilacja pod nowy C++ już wyraźnie mówi, że to bez sensu: http://ideone.com/kZU3s4

no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and 'std::ostream {aka std::basic_ostream<char>}')
friend ostream& operator<<(ostream& out,osoba& ob){out << ob.wypisz(out);}

Wynika to z faktu, że wypisz zwraca ostream&, a potem próbujesz ten obiekt wyrzucać do strumienia.

0

Jakoś nie daję mi to spokoju poprosiłem kolegę, by podał swój kod i jego się poprawnie kompiluje (przynajmniej u mnie, nie wyskakują żadne zbędne adresy) . Szczerze, nie wiem czym jego kod różni się od mojego (nie licząc, że dodał klauzule try,catch i pole statyczne, by zliczyc obiekty) .

Może wy byście mogli zerknąć na kod i wskazać, czym on się właściwie rożni od mojego, że mu nie wyskakują te adresy ? ;)

 
#include <iostream>

using namespace std;

class osoba{
	protected:
		string *_imie;
		string _nazwisko;
		static unsigned _liczba;
	public:
		osoba(): _imie(new string("brak")), _nazwisko("brak") {_liczba++;}
		osoba(const string& imie, const string& nazwisko): _imie(new string(imie)), _nazwisko(nazwisko) {_liczba++;}
		osoba(const osoba& os): _imie(new string(*os._imie)), _nazwisko(os._nazwisko) {_liczba++;}
		virtual ostream& wypisz(ostream&) const throw (string);
		friend ostream& operator<< (ostream&, const osoba&);
		osoba& operator= (const osoba& os);
		virtual ~osoba() {delete _imie; _liczba--;}
};

ostream& osoba::wypisz(ostream& out)const  throw (string)
{
	if ((*_imie == "brak") && (_nazwisko == "brak"))
		throw string("Brak danych o osobie!\n");
	return out << *_imie << " " << _nazwisko << endl;
}

ostream& operator<< (ostream& out, const osoba& os)
{
	return os.wypisz(out);
}

osoba& osoba::operator= (const osoba& os)
{
	if(this != &os)
	{
		*_imie = *os._imie;
		_nazwisko = os._nazwisko;
	}
	return *this;
}


class student: public osoba{
	private:
		string _kierunek;
		unsigned _rok;
	public:
		student(): osoba(), _kierunek("brak"), _rok(0) {_liczba++;}
		student(const osoba& os): osoba(os), _kierunek("brak"), _rok(0) {_liczba++;}
		student(const osoba& os, const string& kier, const unsigned rok): osoba(os), _kierunek(kier), _rok(rok) {_liczba++;}
		student(const string& imie, const string& naz, const string& kier, const unsigned rok): osoba(imie, naz), _kierunek(kier), _rok(rok) {_liczba++;}
		student(const student& st): osoba(st), _kierunek(st._kierunek), _rok(st._rok) {_liczba++;}

		ostream& wypisz(ostream& out) const throw (string);

		student& operator=(const student&);

		~student() {_liczba--;}
};

ostream& student::wypisz(ostream& out)const throw (string)
{
	if ((*_imie == "brak") && (_nazwisko == "brak") && (_kierunek == "brak") && (_rok == 0))
		throw string("Brak danych o studencie!\n");
	return out << *_imie << " " << _nazwisko << " " << _kierunek << " " << _rok << endl;
}

student& student::operator=(const student& st)
{
	if(this != &st)
	{
		osoba::operator=(st);
		_kierunek = st._kierunek;
		_rok = st._rok;
	}
	return *this;
}


unsigned osoba::_liczba = 0;

int main()
{
	const osoba o1("Jan", "Kowalski");
	const osoba o2("Ewa", "Nowak");

	osoba* tab[5];

	tab[0] = new osoba;
	tab[1] = new student;
	tab[2] = new osoba("Ala", "Kot");
	tab[3] = new student(o1);
	tab[4] = new student(o2, "Informatyka", 3);

	for(int i = 0; i < 5; i++)
		try
		{
			cout << *tab[i] << endl;
		}
		catch (const string& err)
		{
			cerr << err << endl;
		}

	cout << "**********" << endl;

	return 0;
}

2
friend ostream& operator<<(ostream& out,osoba& ob){out << ob.wypisz(out);}
ostream& operator<< (ostream& out, const osoba& os)
{
    return os.wypisz(out);
}

Zagadka, znajdź 3 różnice.

0

Super, wszystko działa ! dziękuję ;)

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