2012-02-06 10 views
14

Jest to kod:Przypisanie operator dziedziczenie

#include <iostream> 

class Base { 
public: 
    Base(){ 
     std::cout << "Constructor base" << std::endl; 
    } 
    ~Base(){ 
     std::cout << "Destructor base" << std::endl; 
    } 
    Base& operator=(const Base& a){ 
     std::cout << "Assignment base" << std::endl; 
    } 
}; 

class Derived : public Base{ 
public: 

}; 

int main (int argc, char **argv) { 
    Derived p; 
    Derived p2; 
    p2 = p; 
    return 0; 
} 

Wyjście po kompilacji przez g ++ 4.6:

Constructor base 
Constructor base 
Assignment base 
Destructor base 
Destructor base 

Dlaczego operator przypisania klasy podstawowej jest nazywany altough mówi się, że operator przypisania nie jest dziedziczny?

+1

możliwy duplikat [Problem z dziedziczeniem operatora = w C++] (http://stackoverflow.com/questions/3882186/trouble-with-inititance-of-operator-in-c) –

Odpowiedz

13

Nie mają domyślne

Derived& operator=(const Base& a); 

w swojej klasie Derived.

domyślny operator przypisania, jednak tworzone są:

Derived& operator=(const Derived& a); 

a to wymaga od operatora przypisania Base. Tak więc nie jest to dziedziczenie operatora przypisania, ale wywoływanie go za pośrednictwem domyślnego generowanego operatora w klasie pochodnej.

+9

operator = jest dziedziczony z klasy bazowej, jak cytuję ze standardu 98 C++ "Funkcje operatora są dziedziczone w taki sam sposób, jak inne funkcje klasy podstawowej. " Właśnie został ukryty przez niejawnie utworzony operator = dla klasy pochodnej. – Gob00st

+1

"Właśnie został ukryty przez niejawnie utworzony operator = dla klasy pochodnej". Podobnie jak w przypadku, gdy klasa bazowa ma pustkę func (int), a klasa pochodna ma void func (double), funkcja klasy podstawowej void func (int) jest ukryta. Na podobnych liniach operator klasy podstawowej = jest ukryty przez operator klasy pochodnej =. – Sandeep

+0

... i dla jasności, ponieważ bazowy 'operator =' został tylko ukryty, można go wyłączyć w klasie pochodnej za pomocą 'using Base :: operator =;' i boom: tam jest, dziedziczony. Zobacz: http://stackoverflow.com/questions/4122214/dhy-operator-doesnt-in-inited-od-a-top-klasy-klasy –

-1

Wynika to z faktu, że domyślny operator przypisania utworzył wywołania, jest operatorem przypisania podstawowego, tj. Nie jest dziedziczony, ale nadal jest wywoływany jako część domyślnego operatora przypisania.

+0

Operator przypisania ** to ** odziedziczone po bazie. Jest po prostu ukryty przez wygenerowany przez kompilator w klasie pochodnej. Użycie 'using Base :: operator =;' udowodniłoby to, odkrywając podstawową implementację i udostępniając ją poprzez klasę pochodną. Zobacz: http://stackoverflow.com/questions/4122214/dhy-operator-doesnt-get-inher--top-a-topplate-class –

31

W rzeczywistości to, co się nazywa, to domyślnie zdefiniowany operator = dla Derived. Definicja dostarczona przez kompilator z kolei wywołuje operator = dla Base i widać odpowiednie wyjście. To samo dotyczy konstruktora i destruktora. Po opuszczeniu go do kompilatora do definiowania operator =, definiuje ją następująco:

Derived& operator = (const Derived& rhs) 
{ 
    Base1::operator =(rhs); 
    ... 
    Basen::operator =(rhs); 
    member1 = rhs.member1; 
    ... 
    membern = rhs.membern; 
} 

gdzie Base1,...,Basen są podstawy tej klasy (w kolejności określając je na liście spadkowego) oraz member1, ..., membern są członkowie Pochodzące (nie licząc członków, które zostały odziedziczone) w kolejności, w jakiej je zadeklarowaliście w definicji klasy.

-1

Operator przypisania faktycznie nie jest dziedziczony. Dziedziczenie tego operatora umożliwiłoby przypisanie Base do Derived, jednak Base b; p = a; (prawnie) nie skompiluje się.

Co się dzieje, że kompilator generuje operator=, ponieważ nie zdefiniowano niestandardowego dla Derived. Autogenerowany operator= wywoła operatorów przypisania wszystkich klas bazowych i wszystkich członków. W tym aspekcie jest on bardzo podobny do konstruktorów/destruktorów, które również wywołują odpowiednią funkcję we wszystkich Bazach/elementach.

+1

Operator przypisania ** jest ** dziedziczony z bazy. Jest po prostu ukryty przez wygenerowany przez kompilator w klasie pochodnej. Użycie 'using Base :: operator =;' udowodniłoby to, odkrywając podstawową implementację i udostępniając ją poprzez klasę pochodną. Zobacz: http://stackoverflow.com/questions/4122214/dhy-operator-doesnt-in-inited- from-a-template-class –

7

standardowe mówi (12,8)

Operator zadanie zostanie zrealizowane przez niż statyczna składowa funkcji z dokładnie jednym parametrem. Ponieważ operator przypisania = jest domyślnie zadeklarowany dla klasy, jeśli nie został zadeklarowany przez użytkownika (12,8) jako , operator przypisania klasy podstawowej jest zawsze ukryty przez operatora przydziału kopiowania klasy pochodnej.

i przypisania operatora pochodnych wywołać baza

niejawnie zdefiniowane przez operatora przypisania kopii/przejście przez nie związków klasy X wykonuje memberwise kopiowaniem/przenoszenie przyporządkowanie jej podobiektów. Bezpośrednie klasy bazowe X są przydzielane jako pierwsze, w kolejności ich deklaracji na liście specyfikatora bazowego, a następnie nielimitowane elementy danych X są przypisywane w kolejności, w jakiej zostały zadeklarowane w definicji klasy.

17

Można również użyć "za":

class Derived : public Base{ 
public: 
    using Base::operator=; 
}; 

http://en.cppreference.com/w/cpp/language/using_declaration

czytam ten post kilka razy, zanim ktoś pomógł mi z tym.

+2

W końcu ktoś to powiedział. +1. Zobacz także: http://stackoverflow.com/questions/4122214/dhy-operator-doesnt-get-inher--top-a-template-class –