operator = e funzioni che non sono ereditate in C ++?

Fino a un test che ho appena realizzato, ho creduto che solo i costruttori non fossero ereditati in C ++. Ma a quanto pare, l’ operator= assegnazione operator= non è troppo …

  1. Qual è la ragione di ciò?
  2. C’è qualche soluzione alternativa per ereditare l’operatore di assegnazione?
  3. È anche il caso operator+= , operator-= , …?
  4. Tutte le altre funzioni (tranne costruttori / operatore =) sono ereditate?

In effetti, ho riscontrato questo problema mentre stavo facendo un po ‘di CRTP:

 template class Base { inline Crtp& operator=(const Base& rhs) {/*SOMETHING*/; return static_cast(*this);} }; class Derived1 : public Base { }; class Derived2 : public Base { }; 

C’è qualche soluzione per farlo funzionare?

EDIT: OK, ho isolato il problema. Perché il seguente non funziona? Come risolvere il problema ?

 #include  #include  // Base class template<template class CRTP, typename T, unsigned int N> class Base { // Cast to base public: inline Base& operator()() { return *this; } // Operator = public: template<typename T0, class = typename std::enable_if<std::is_convertible::value>::type> inline CRTP& operator=(const T0& rhs) { for (unsigned int i = 0; i < N; ++i) { _data[i] = rhs; } return static_cast<CRTP&>(*this); } // Data members protected: T _data[N]; }; // Derived class template class Derived : public Base { }; // Main int main() { Derived x; x() = 3; // <- This is OK x = 3; // <- error: no match for 'operator=' in ' x=3 ' return 0; } 

L’operatore di assegnazione è tecnicamente ereditato; tuttavia, è sempre nascosto da un operatore di assegnazione definito esplicitamente o implicitamente per la class derivata (vedere i commenti di seguito).

(13.5.3 Assegnazione) Un operatore di assegnazione deve essere implementato da una funzione membro non statico con esattamente un parametro. Poiché un operatore operator= assegnazione copia operator= viene implicitamente dichiarato per una class se non dichiarato dall’utente, un operatore di assegnazione class base viene sempre nascosto dall’operatore di assegnazione copia della class derivata.

È ansible implementare un operatore fittizio di assegnazione che semplicemente inoltra la chiamata all’operatore della class base operator= , in questo modo:

 // Derived class template class Derived : public Base { public: template::value>::type> inline Derived& operator=(const T0& rhs) { return Base::operator=(rhs); } }; 

L’operatore di assegnazione è ereditato, in una sorta, ma … In qualsiasi class data, se non si fornisce un operatore di assegnazione copia, il compilatore ne genera uno. Ciò significa che le tue classi derivate hanno effettivamente un operatore di assegnazione:

 Derived& operator=( Derived const& ); 

E si applicano le solite regole nascoste; questo nasconde tutti gli operatori di assegnazione della class base. (Se la class base avesse un operatore di assegnazione con questa firma, la class derivata la erediterebbe normalmente).

  1. Il tuo operatore di assegnazione è tecnicamente ereditato, ma poi è nascosto dall’operatore di assegnazione della copia predefinito nella class derivata. Questo assegnamento di copia predefinito tenta quindi di richiamare l’assegnazione di copia della class base che non esiste poiché l’hai nascosta con il tuo stesso incarico.

  2. Il modo più efficace per risolvere questo problema è non utilizzare l’overloading dell’operatore in modi non ovvi ( = non significa assegnazione di copia per esempio). In questo caso, non utilizzare operator= : chiamalo qualcosa come assign o set e quindi erediterà e non sarà nascosto dall’assegnazione di copia figlio.

  3. Questi operatori sono ereditati e non ci sono versioni del compilatore quindi non saranno mai nascosti automaticamente come operator= .

  4. In realtà sono solo i costruttori che non sono ereditati e non posso pensare a nessun’altra funzione generata dal compilatore che possa hide qualcosa dal genitore come in operator= .