czy jest jakiś magiczny sposób aby móc pokazać bez wątpliwości kiedy zostaje uruchomiony konstruktor kopiujący a kiedy operator przypisania? (zakładając że operator przypisania jest napisany przez programistę)
sprecyzuj o co ci chodzi bo ten temat jest dość obszerny.
Jeśli nie jesteś w stanie zawęzić tematu polecam "Symfonię C++" Grębosza.
Klasa
{
Klasa(const Klasa &k): { cout << "konstruktor"; }
Klasa& operator=(const Klasa &k): { cout << "operator"; }
}
?
#include <iostream>
using namespace std;
/*---------------------- Klasa tekst ---------------*/
class tekst{
char *znaki;
public:
tekst();
tekst(const tekst &jakisTekst);
tekst(const char *init_string);
~tekst(){delete[](znaki);};
tekst& operator=(const tekst &drugiTekst);
char& operator[](int n);
friend tekst operator+(const tekst &pierwszyTekst,const tekst &drugiTekst);
int dlugosc() const{return strlen(znaki);};
friend ostream & operator<<(ostream &stream, tekst jakisTekst);
};
/*___________________________________________________________________________*/
tekst::tekst(){
znaki = new char[1];
if(znaki==NULL) {cout << "Brak pamieci!\n";exit(0);};
znaki[0]='\0';
}
/*___________________________________________________________________________*/
tekst::tekst(const tekst &oryginal){
znaki=new char[1+strlen(oryginal.znaki)];
if(znaki==NULL) {cout << "Brak pamieci!\n";exit(0);};
strcpy(znaki, oryginal.znaki);
}
/*___________________________________________________________________________*/
tekst::tekst(const char *lancuchZnakow){
znaki = new char[1+strlen(lancuchZnakow)];
if(znaki==NULL) {cout << "Brak pamieci!\n";exit(0);}
strcpy(znaki, lancuchZnakow);
}
/*___________________________________________________________________________*/
tekst& tekst::operator=(const tekst &drugiTekst){
delete znaki;
znaki = new char[1+drugiTekst.dlugosc()];
if(znaki==NULL) {cout << "Brak pamieci!\n";exit(0);};
strcpy(znaki, drugiTekst.znaki);
return *this;
}
/*___________________________________________________________________________*/
char& tekst::operator[](int n){
static char no_char='\0';
if (n>=0 && n<dlugosc()) return znaki[n];
else return no_char;
}
/*___________________________________________________________________________*/
tekst operator+(const tekst &pierwszyTekst, const tekst &drugiTekst){
tekst wynik;
delete wynik.znaki;
wynik.znaki = new char[1+pierwszyTekst.dlugosc()+drugiTekst.dlugosc()];
if(wynik.znaki==NULL) {cout << "Brak pamieci!\n";exit(0);};
strcpy(wynik.znaki, pierwszyTekst.znaki);
strcat(wynik.znaki, drugiTekst.znaki);
return wynik;
}
/*___________________________________________________________________________*/
ostream & operator<<(ostream &out, tekst jakisTekst){
out << jakisTekst.znaki;
return out;
}
/*___________________________________________________________________________*/
int main(){
tekst alfa="Programowanie obiektowe";
cout << alfa << "\n";
cout << alfa[3] << alfa[7] << alfa[10] << alfa[19] << "\n";
alfa[0]='p'; alfa[13]='-';
cout << alfa << "\n";
tekst beta=alfa;
tekst c="ccc";
c[1]=c[2]='d';
beta=alfa=c;
cout << beta << " , " << alfa << endl;
system("pause");
}
w tym przypadku...kiedy który?? nie umiem tego zczaić :/
a co do grębosza to ja uważam że jest do kitu - wole prate "szkola programowania: jezyk c++"
- Zapomniałeś, o destruktorze.
- dopisz sobie logi tak jak zasugerował adf88 lub przedebuguj program, żeby zobaczyć co i jak.
- dopisałbym jeszcze prywatny konstruktor, bu go wykorzystać w operatorze dodawania:
tekst::tekst( int expectedSize ){
znaki=new char[1+expectedSize ];
if(znaki==NULL)
{cout << "Brak pamieci!\n";exit(0);}
}
Pamiętaj, że zwracanie przez wartość powoduje kilkukrotne wywołanie copy-konstruktora (o ile dobrze pamiętam 3 kotne).
a to:
~tekst(){delete[](znaki);};
??
Sorry nie zauważyłem, że jest zapisany w deklaracji klasy :/
spoko;
zrobiłem jak napisał adf88, wszystko wiem, ale kurcze czemu tyle tych konstruktorów sie włącza...
a to że jeden konstruktor przyjmuje wskaźnik a druga referencje to czy w tym może być jakiś haczyk?
Konstruktor kopiujący uruchamia się jeśli przypisujesz wartośc w chwili tworzenia obiektu
klasa obiekt2=obiekt1;
W innych przypadkach uruchamia się operator przypisania.
ne0 napisał(a)
tekst::tekst(){
znaki = new char[1];
if(znaki==NULL) {cout << "Brak pamieci!\n";exit(0);};
znaki[0]='\0';
}
W przypadku błędu alokacji new ma obowiązek rzucić std::bad_alloc; jeśli chcesz sprawdzać w ten sposób musisz pisać:
new (nothrow) co
Ale to nie ma sensu - łap ten wyjątek, teraz kod powtarzasz.