避免在 const 和非 const getter 方法中重复代码
在 C++中,只有 const
限定符的方法可以重载。有时可能需要两个版本的 getter 返回对某个成员的引用。
让 Foo
成为一个类,它有两个执行相同操作的方法,并返回对 Bar
类型的对象的引用:
class Foo
{
public:
Bar& GetBar(/* some arguments */)
{
/* some calculations */
return bar;
}
const Bar& GetBar(/* some arguments */) const
{
/* some calculations */
return bar;
}
// ...
};
它们之间的唯一区别是一个方法是非 const 并返回一个非 const 引用(可用于修改对象),第二个是 const 并返回 const 引用。
为了避免代码重复,有一种诱惑从另一种方法中调用一种方法。但是,我们不能从 const 中调用非 const 方法。但我们可以从非 const 方法调用 const 方法。这将需要使用’const_cast’来删除 const 限定符。
解决方案是:
struct Foo
{
Bar& GetBar(/*arguments*/)
{
return const_cast<Bar&>(const_cast<const Foo*>(this)->GetBar(/*arguments*/));
}
const Bar& GetBar(/*arguments*/) const
{
/* some calculations */
return foo;
}
};
在上面的代码中,我们通过将其转换为 const 类型:const_cast<const Foo*>(this)
,从非 const GetBar
调用 GetBar
的 const 版本。因为我们从非 const 调用 const 方法,所以对象本身是非 const 的,并且允许抛弃 const。
检查以下更完整的示例:
#include <iostream>
class Student
{
public:
char& GetScore(bool midterm)
{
return const_cast<char&>(const_cast<const Student*>(this)->GetScore(midterm));
}
const char& GetScore(bool midterm) const
{
if (midterm)
{
return midtermScore;
}
else
{
return finalScore;
}
}
private:
char midtermScore;
char finalScore;
};
int main()
{
// non-const object
Student a;
// We can assign to the reference. Non-const version of GetScore is called
a.GetScore(true) = 'B';
a.GetScore(false) = 'A';
// const object
const Student b(a);
// We still can call GetScore method of const object,
// because we have overloaded const version of GetScore
std::cout << b.GetScore(true) << b.GetScore(false) << '\n';
}