Wywołanie operatora<< dla wyłuskanego obiektu klasy

0

Problem pojawia się w wywołaniu przeciążonego operatora klasy BirdHouse:

 
ostream& operator<<(ostream& os, BirdHouse& b){
	os<<b.bird<<endl<<b.bird_ref<<endl<<*b.bird_ptr<<endl;
	return os;
}

Konstruktora BirdHouse w ten sposób inicjalizuje bird_ptr:

BirdHouse(Bird b1,Bird b2,Bird b3):bird(b1),bird_ptr(&b2),bird_ref(b3){}

W ten sposób tworze obiekt klasy BirdHouse:

Bird b1,b3,b4;
BirdHouse bg (b1,b3,b4);

Kompilator nie zgłasza błędów. Program zawiesza się dopiero gdy próbuje wywołać przeciążony operator<< dla wyłuskanego ze wskaźnika b.bird_ptr obiektu Bird.

Tutaj operator<< dla obiektu Bird:

ostream& operator<< (ostream& os,const Bird& b){
	os<<b.napis<<endl;
	return os;
} 

Przy debugowania pojawia się błąd : Access violation reading location 0xcccccccc.

Co może być przyczyną?

Poniżej pełen kod programu:

 
#include "stdafx.h"

#include <iostream>
using namespace std;
#include <string>

class Bird{
	string napis;
	static int licznik;
public:
		
	Bird():napis("Bird # "){
		itoa(licznik++,(char*)napis.c_str()+6,10);
	}
	friend ostream& operator<<(ostream&,const Bird&);
	Bird& operator=(const Bird& b){
		if(this==&b){return *this;}
		napis=b.napis;
		return *this;
	}
	Bird(const Bird& b){
		napis=b.napis;
	}
}b;

int Bird::licznik=0;

ostream& operator<< (ostream& os,const Bird& b){
	os<<b.napis<<endl;
	return os;
}

class BirdHouse {
	Bird bird;
	Bird* bird_ptr;
	Bird& bird_ref;
public:
	BirdHouse(Bird b1,Bird b2,Bird b3):bird(b1),bird_ptr(&b2),bird_ref(b3){}

	friend ostream& operator<<(ostream&, BirdHouse&);

	BirdHouse& operator=(const BirdHouse& bh){
		if(this==&bh){return *this;}
		bird=bh.bird;
		*bird_ptr=*bh.bird_ptr;
		bird_ref=bh.bird_ref;
	}

	BirdHouse(const BirdHouse& bh):bird_ref(*(new Bird)){
		bird=bh.bird;
		bird_ptr=new Bird;
		*bird_ptr=*bh.bird_ptr;
		bird_ref=bh.bird_ref;
	}

};

ostream& operator<<(ostream& os, BirdHouse& b){
	os<<b.bird<<endl<<b.bird_ref<<endl<<*b.bird_ptr<<endl;
	return os;
}

int _tmain(int argc, _TCHAR* argv[])
{
	Bird b1,b3,b4;
	BirdHouse bg (b1,b3,b4);
	cout<<bg;
	return 0;
}

1

Argumenty przekazywane do konstruktora są przez kopię, przez co zaraz po wykonaniu się konstruktora są niszczone, i zarówno b2 jak i b3 kierują na niewłaściwy obszar pamięci.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.