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);
}
网友评论