Exceptional C++

【Exceptional C++(25)】正确使用const

2018-01-30  本文已影响2人  downdemo
class Polygon {
public:
    Polygon() : area_(-1) {}
    void AddPoint(Point pt) { // Point对象传值,所以没必要为const
        InvalidateArea();
        points_.push_back(pt);
    }
    const Point GetPoint(int i) const { // 同理,const值传递没什么意义
        // 但成员函数应该定义为const,因为不改变对象状态
        return points_[i]; // 返回类型不是内置类型通常应该返回const
    }
    int GetNumPoints() const { // 同上,函数本身应该声明为const
        return points_.size(); // 返回的int已经是一个右值类型,不用返回const
    }
    double GetArea() const { // 虽然修改了对象内部状态,但还是应该为const
        // 因为被修改对象的可见状态没变,所以area_要声明为mutable
        if (area_ < 0) CalcArea();
        return area_;
    }
private:
    void InvalidateArea() const { // 仅仅处于一致性考虑也该声明为const
        area_ = -1;
    }
    void CalcArea() const { // 必须是const,至少会被另一个const函数GetArea()调用
        area_ = 0;
        vector<Point>::const_iterator i; // 不改变points_状态所以用const_iterator
        for(i = points_.begin(); i != points_.end(); ++i)
            area_ += /* some work*/
    }
    vector<Point> points_;
   mutable double area_;
};
const Polygon operator+(const Polygon& lhs,
    const Polygon& rhs) { // 传const引用而非传值
    Polygon ret = lhs;
    const int last = rhs.GetNumPoints(); // 返回值是const,last不改变所以也是const
    for(int i = 0; i < last; ++i)
        ret.AddPoint(rhs.GetPoint(i));
    return ret; // 返回类型是const
}

void f(const Polygon& poly) {
    const_cast<Polygon&>(poly).AddPoint(Point(0, 0));
}
// 如果被引用的对象被声明为const这里的结果是未定义的
// 应该改成这样
void f(Polygon& rPoly) {
    rPoly.AddPoint(Point(0, 0));
}

void g(Polygon& const rPoly) { // 这里的const毫无作用
    // 因为引用不可能改变指向另一个对象
    rPoly.AddPoint(Point(1, 1));
}
// 应该改成这样
void g(Polygon& rPoly) {
    rPoly.AddPoint(Point(1, 1));
}

void h(Polygon* const pPoly) { // 这里的const也不起作用
    // 因为不会去修改指针地址
    pPoly->AddPoint(Point(2, 2));
}
// 应该改成这样
void h(Polygon* pPoly) {
    pPoly->AddPoint(Point(2, 2));
}
int main() {
    Polygon poly;
    f(poly);
    g(poly);
    h(&poly);
}
上一篇下一篇

猜你喜欢

热点阅读