C++ jest zbyt uprzejmy.

0
class Base {
private:
    int a;
public:
    Base(){}
    Base( int a ) : a(a) { }

    Base& operator=(const Base& rhs){   }
    void setA(int a){ this->a = a;}
    int getA(){ return a;}
};

class Derived : public Base {
public:
    int getB(){ return b;}
    Derived(int b) :  b(b){}


    Derived& operator=(const Derived& rhs){
        this->b = rhs.b;
    }
private:
    int b;
};

int main() {
    Base b(3);
    Derived d(9);
    d.setA(44);

    Derived cd = d;


    cout << cd.getA() << " " <<  cd.getB() << endl;

    return 0;
}

W powyższym kodzie jak widać podejmuję decyzję, że sam zdefinuję sobie operatory =. Jak widać w klase bazowej nie chcę, aby cokolwiek było kopiowane.
Stąd pytanie, skąd obiek cd ma wartość w składowej a wartość 44 skoro ja nie dopusczam do kopiowania? ( pomijam już fakt, że ja powinienem explicite wołać operator przypisania dla klasy Base w klasie Derived jeżeli chciałbym żeby została zdefiniowana część Base.
Skąd taka uprzejmość C++, wbrew temu co pisze Scott Meyers w ( bądź co bądź dość starej ) książce Effective C++?

2

Bo został użyty konstruktor kopiujący a nie operator =

 #include <iostream>

using namespace std;

class Base {
private:
    int a;
public:
    Base(){}
    Base( int a ) : a(a) { }
 
    Base& operator=(const Base& rhs) {}
    Base(const Base& rhs) {}
    void setA(int a){ this->a = a;}
    int getA(){ return a;}
};
 
class Derived : public Base {
public:
    int getB(){ return b;}
    Derived(int b) :  b(b){}
 
 
    Derived& operator=(const Derived& rhs){
        this->b = rhs.b;
    }
private:
    int b;
};
 
int main() {
    Base b(3);
    Derived d(9);
    d.setA(44);
 
    Derived cd = d;
 
 
    cout << cd.getA() << " " <<  cd.getB() << endl;
 
    return 0;
}

http://ideone.com/DnuA0L

0

a dlaczego pozwolił sobie na taką bezczelność skoro pisze wprost: '='.
W takim razie:
Kiedy jest użyty konstruktor kop, a kiedy op=?

1

Konstruktor kopiujący użyty jest tylko w momencie inicjalizowania obiektu jakąś(jakimiś) wartością(wartościami), operator przypisania może tylko przypisać wartość do już istniejącego i zainicjalizowanego wcześniej obiektu.

4

Bo to:

T x = y;

nazywa się copy initialization.

Operator przypisania nie jest brany pod uwagę.

W przypadku Twojego kodu poszukiwany jest konstruktor konwertujący (czyli taki, który nie jest explicit i wymaga jednego argumentu) w klasie Derived, który przyjmuje argument typu Derived. Oczywiście jest to konstruktor kopiujący, który zostanie wygenerowany przez kompilator.

0
    Derived b(3); // konstruktor
    Derived d(9); // konstruktor
 
    Derived cd = d; // konstruktor kopiujący
    cd = b; // operator przypisania
0

Oczywiście jest to konstruktor kopiujący, który zostanie wygenerowany przez kompilator.

Ponoć kompilator nie generuje konstruktorów sam, jeżeli weźmie się za to user. Jak to jest?

Dla tego:

cd = b; // operator przypisania

też obydwie wartości się kopiują i nie wiem dlaczego.

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