Как говорили в пункте 33 в «более эффективные C++», проблема присваиванияКак абстрактный базовый класс избегает частичного присвоения?
//Animal is a concrete class
Lizard:public Animal{};
Chicken:public Animal{};
Animal* pa=new Lizard('a');
Animal* pb=new Lizard('b');
*pa=*pb;//partial assignment
Однако, если я определяю Animal
как абстрактный базовый класс, мы можем скомпилировать и запустить предложение: *pa=*pb
. Проблема частичного присваивания все еще существует.
Смотрите мой пример:
#include <iostream>
class Ab{ private: int a;
double b;
public:
virtual ~Ab()=0;
};
Ab::~Ab(){}
class C:public Ab{
private:
int a;
double b;
};
class D:public Ab{
private:
int a;
double b;
};
int main()
{
Ab *pc=new C();
Ab *pd=new D();
*pc=*pd;
return 0;
}
ли я что-то пропустила? Тогда каков реальный смысл абстрактного базового класса?
Я получил ответ сам. Я пропустил фрагмент кода в книге.
Использовать защищенный operator=
в базовом классе, чтобы избежать *pa=*pb
. Используйте абстрактный базовый класс, чтобы избежать animal1=animal2
.Затем единственным разрешенным выражения lizard1=lizard2;chicken1=chicken2;
Смотрите код ниже:
#include <iostream>
class Ab{
private:
int a;
double b;
public:
virtual ~Ab()=0;
protected: //!!!!This is the point
Ab& operator=(const Ab&){...}
};
Ab::~Ab(){}
class C:public Ab{
public:
C& operator=(const C&){...}
private:
int a;
double b;
};
class D:public Ab{
public:
D& operator=(const D&){...}
private:
int a;
double b;
};
int main()
{
Ab *pc=new C();
Ab *pd=new D();
*pc=*pd;
return 0;
}
Так животное является конкретным или абстрактным? и вы дважды написали «pa» (в вашем коде нет «pb»). – flyman
@flyman Извините, я только что исправил свои ошибки и дал понять, что понял. – particle128
Попробуйте с чистой виртуальной функцией, которая не является деструктором. – johnbakers