现在的位置: 首页 > 综合 > 正文

常见错误30: 截切问题—-读书笔记《C++ gotchas》

2014年10月27日 ⁄ 综合 ⁄ 共 1119字 ⁄ 字号 评论关闭

截切问题发生在企图把一个派生类对象复制到一个基类对象。

那些派生类专属的数据和行为会被切除,这是一种错误。

class Employee {

public:

    virtual ~Employee();

    virtaul void pay() const;

    //…

protected:

    void setType(int type) {

        myType_ = type;

    }

private:

    int myType_;

};

class Salaried : public Employee {

    //…

};

Employee employee;

Salaried salaried;

employee = salaried;//发生了截切

从salaried到employee的赋值操作时合法的,因为Salaried class对象is-a Employee class 对象,

但是结果可能非我们想要的。

在实践中,被截切之class对象的状态与行为脱节,是难以察觉的,引发的破坏就更大。

截切问题的最常见来源是一个派生类的class对象被以传值(by value)传递给一个基类类型的形参。

void fire(Employee victim);//函数名“解雇”,形参“倒霉蛋”

//…

fire(sllaried);//被截切

此问题可以用传递引用或指针(by reference/by pointer)方式来避免。

void rightSize(Employee &asset);

//…

rightSize(salaried);//正确

截切问题也可能以其它形式出现,尽管不常见。比如说,把一个派生类的基类类型子对象复制到另一个派生类

的基类类型子对象。

Employee *getNextEmployee();

//获取一个Employee的动态对象

//…

Employee *ep = getNextEmployee();

*ep = salaried;//截切

如果发生了截切问题,意味着继承体系设计中存在不周。

最好是避免让具体类(concrete class)成为基类。

class Employee {

public:

    virtual ~Employee();

    virtual void pay() const = 0;

    //…

};

void fire(Employee);//编译出错

void rightSize(Employee &);//正确

Employee *getNextEmployee();//没问题

Employee *ep = getNextEmployee();//正确

*ep = salaried;//编译错误

Employee e2(salaried);//编译错误

抽象类不能够被具现,所以大多数引发截切的问题都会在编译期截获。

抱歉!评论已关闭.