More Effective C++笔记
将非尾端设计成抽象类
多态型对象赋值
class Animal
{
public:
Animal &operator=(const Animal& rhs) { return *this; };
};
class Lizard : public Animal
{
public:
Lizard &operator=(const Lizard& rhs) { return *this; };
};
class Chicken : public Animal
{
public:
Chicken &operator=(const Chicken& rhs) { return *this; };
};
void test01()
{
Lizard liz1;
Lizard liz2;
Animal *pAni1 = &liz1;
Animal *pAni2 = &liz2;
*pAni1 = *pAni2; //调用Animal::operator=, Animal *指针具有多态性,只进行部分赋值
}
声明成虚函数
class Animal
{
public:
virtual Animal &operator=(const Animal& rhs) { return *this; };
};
class Lizard : public Animal
{
public:
virtual Lizard &operator=(const Animal& rhs) { return *this; };
};
class Chicken : public Animal
{
public:
virtual Chicken &operator=(const Animal& rhs) { return *this; };
};
void test02()
{
#if 0
Lizard liz1;
Lizard liz2;
Animal *pAni1 = &liz1;
Animal *pAni2 = &liz2;
*pAni1 = *pAni2; //调用Lizard::operator=
#endif // 0
Lizard liz;
Chicken chick;
Animal *pAni1 = &liz;
Animal *pAni2 = &chick;
*pAni1 = *pAni2; //调用Lizard::operator= chick赋值給liz不合理
}
dynamic_cast解决混合类型赋值
class Animal
{
public:
virtual Animal &operator=(const Animal& rhs) { return *this; };
};
class Lizard : public Animal
{
public:
virtual Lizard &operator=(const Animal& rhs)
{
//make sure rhs is really a lizard
const Lizard& rhs_liz = dynamic_cast<const Lizard&>(rhs);
//給类成员赋值...
return *this;
};
};
class Chicken : public Animal
{
public:
virtual Chicken &operator=(const Animal& rhs) { return *this; };
};
void test03()
{
Lizard liz;
Chicken chick;
Animal *pAni1 = &liz;
Animal *pAni2 = &chick;
*pAni1 = *pAni2; //调用Lizard::operator= 抛出bad_cast异常
}
增加一个通常形式的赋值操作
class Animal
{
public:
virtual Animal &operator=(const Animal& rhs) { return *this; };
};
class Lizard : public Animal
{
public:
virtual Lizard &operator=(const Animal& rhs)
{ return operator=(dynamic_cast<const Lizard&>(rhs)); };
Lizard &operator=(const Lizard& rhs) { return *this; };
};
class Chicken : public Animal
{
public:
virtual Chicken &operator=(const Animal& rhs) { return *this; };
};
void test04()
{
Lizard liz;
Lizard liz2;
liz = liz2; //调用Lizard::operator=(const Lizard& rhs)
Chicken chick;
Animal *pAni1 = &liz;
//Animal *pAni2 = &liz2; //可以
Animal *pAni2 = &chick; //抛出bad_cast异常
*pAni1 = *pAni2; //调用Lizard::operator=(const Animal& rhs)
}
将Animal operator=置为private,使在编译器报错
class Animal
{
protected:
virtual Animal &operator=(const Animal& rhs) { return *this; };
};
class Lizard : public Animal
{
public:
Lizard &operator=(const Lizard& rhs) { return *this; };
};
class Chicken : public Animal
{
public:
Chicken &operator=(const Animal& rhs) { return *this; };
};
void test04()
{
Lizard liz;
Chicken chick;
Animal *pAni1 = &liz;
Animal *pAni2 = &chick;
//*pAni1 = *pAni2; //chick赋值給liz调用Animal::operator=报错
//1.Anima对象之间赋值也报错
//2.派生类赋值有责任调用基类赋值函数,将Animal::operator=申明为 protected 来解决
}
使用抽象类
class AbstractAnimal
{
protected:
AbstractAnimal &operator=(const AbstractAnimal& rhs) { return *this; };
public:
virtual ~AbstractAnimal() {};
};
class Animal : public AbstractAnimal
{
protected:
Animal &operator=(const Animal& rhs) { return *this; };
};
class Lizard : public AbstractAnimal
{
public:
Lizard &operator=(const Lizard& rhs) { return *this; };
};
class Chicken : public AbstractAnimal
{
public:
Chicken &operator=(const Animal& rhs) { return *this; };
};
void test04()
{
Lizard liz;
Chicken chick;
AbstractAnimal *pAni1 = &liz;
AbstractAnimal *pAni2 = &chick;
//*pAni1 = *pAni2; //chick赋值給liz调用AbstractAnimal::operator= 没有权限访问(protected)
}