Konstruktor kopiujący - czy dobrze to rozumiem ?

0
#include <iostream>
#include <fstream>
using namespace std;

class K
{
    public:
    int zmienna;
    
    K()
    {
    }
    
    K(K &wzorzec)
    {
        zmienna = 5;
    }
};

void fun_pierwsza(K odebrana)
{
   cout << odebrana.zmienna << endl;
}
int main()
{
    K jeden;
    jeden.zmienna = 2;
    K dwa(jeden);

    cout << dwa.zmienna << endl << jeden.zmienna << endl;
    fun_pierwsza(jeden);

    return 0;
} 

Najpierw dla obiektu jeden jest dla pola zmienna przypisywana wartość 2. Potem tworzymy obiekt dwa korzystając z konstruktora kopiującego. W konstruktorze kopiującym argumentem jest referencja do obiektu - działamy na oryginalnym obiekcie jeden dlatego jednocześnie zmieniamy zawartość pola dla obiektu jeden i dwa ?

0

Zmień

K(K &wzorzec)

na

K(const K &wzorzec)
0

a co to robi ? Bo w wypisach są takie same wartości, dobre mam rozumowanie to co wyżej napisałem ?

1

Skompiluj to i sam się przekonaj jaka jest różnica. Do tego staraj się unikać przekazywania złożonych struktur i klas przez wartość.

#include <iostream>
using namespace std;

namespace Your{
	struct Foo{
		int i = 5;
		Foo(){}
		Foo(Foo &foo){
			i = foo.i;
		}
	};
}

namespace Mine{
	struct Foo{
		int i = 5;
		Foo(){}
		Foo(const Foo &foo){
			i = foo.i;
		}
	};
}


int main(){
	{const Mine::Foo foo, copiedFoo(foo);}
	{const Your::Foo foo, copiedFoo(foo);}
	return 0;
}

http://ideone.com/buFFUn

1

W zasadzie rozumiesz dobrze, z tym że:

  1. Kolega wcześniej podał propozycję poprawki, która zabezpieczy obiekt, z którego wartości będą pobierane. Gdy piszesz konstruktor kopiujący jest to dobre rozwiązanie, bo niepożądane jest, aby zmieniać wartości we wzorcu.
  2. Z tego samego powodu Twój konstruktor kopiujący nie ma sensu (jego definicja). Ale tok rozumowania masz dobry.
  3. Konstruktor kopiujący powinien znaleźć się w klasach, w których są wskaźniki/tablice. Prawidłowo napisany da Ci pewność, że operując na jednym obiekcie nie zmienisz wartości innego obiektu (niecelowo).

UPDATE:
W Twoim konstruktorze kopiującym nie zmieniasz wartości wzorca.

0

Mi z const kompilator tak samo się zachowuje jak bez const.

1

const ma tutaj 2 zadania:

  1. nie pozwala modyfikować obiektu, z którego kopiujesz.
  2. pozwala wywołać konstruktor kopiujący na obiekcie tymczasowym
struct X
{
	X() : value(0) {}
	X(X& rhs) : value(rhs.value) {}
	int value;	
};

X f()
{
	return X();
}

int main() 
{
	X b(f());   // to sie nie skompiluje, chyba że zmienisz parametr konstruktora kopiującego na "const X&"
}

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