Załóżmy mamy bardzo prosty class A
:Czy zasada 3/5 ma zastosowanie do dziedziczenia i wirtualnych destruktorów?
class A {
public:
void SetName(const std::string& newName) {
m_name=newName;
}
void Print() const {
std::printf("A::Print(). Name: %s\n",m_name.c_str());
}
private:
std::string m_name;
};
Chcemy rozszerzyć tę klasę z class B
więc dodamy nasz wirtualny destruktor, zmień członka do virtual
i zmienić private
do protected
do inh:
class A {
public:
virtual ~A() {}
void SetName(const std::string& newName) {
m_name=newName;
}
virtual void Print() const {
std::printf("A::Print(). Name: %s\n",m_name.c_str());
}
protected:
std::string m_name;
};
class B : public A {
public:
virtual void Print() const {
std::printf("B::Print(). Name: %s\n",m_name.c_str());
}
};
Odkąd dodaliśmy destruktor w class A
, musimy stworzyć konstruktora kopiowania i skopiować operację tak jak?
class A {
public:
virtual ~A() {}
A() = default;
A(const A& copyFrom){
*this = copyFrom;
}
virtual A& operator=(const A& copyFrom){
m_name=copyFrom.m_name;
return *this;
};
void SetName(const std::string& newName) {
m_name=newName;
}
virtual void Print() const {
std::printf("A::Print(). Name: %s\n",m_name.c_str());
}
protected:
std::string m_name;
};
Dla mnie wydaje się to zbędne, ponieważ domyślny operator kopiowania i konstruktor kopii robią to samo.
@MarcoA. Destrukcja klasy pochodnej może wymagać zrobienia czegoś ekstra, a destruktor klasy podstawowej musi być wirtualny, jeśli chcesz usunąć wyprowadzone ze wskaźnika do bazy. –
@Angew to dobry powód. Prawo –
Uwaga: należy unikać używania ogólnie "chronionych" elementów danych; ponieważ jeśli nie ściśle kontrolujesz hierarchię dziedziczenia ('final'), straciłeś wszystkie gwarancje dotyczące ogólnego stanu tego elementu. Jest to podobne do zwracania odniesienia niestałego. –