可能重复:
How do I remove code duplication between similar const and non-const member functions?
我有两个成员
A &B::GetA (int i)
{
return *(m_C[m_AtoC[i]]);
}
const A &B::GetA (int i) const
{
return *(m_C[m_AtoC[i]]);
}
现在我只是重复代码,但可能存在很好的方法来做到这一点。我绝对不想处理从const到非const的类型转换。
编辑:所以我想调用另一个成员来避免代码重复。答案 0 :(得分:2)
[注意更正;对不起,最初得错了。]
这是使用const_cast
的合适情况,它允许您通过将调用从非const函数转发到相应的const函数来对代码进行重复数据删除:
A & B::GetA(int index)
{
return const_cast<A &>(static_cast<B const *>(this)->GetA(index));
}
重要的是要注意,这应该只在一个方向上完成:你可以用常量方法实现non-const
方法,但不能反过来实现:GetA()
的常量调用获得对相关对象的持续引用,但由于我们有其他信息,它实际确定可以改变对象,我们可以安全地从结果中抛弃const。
在Scott Meyer的 Effective C ++ 中,甚至还有一章正是关于这种技术。
答案 1 :(得分:1)
您可以执行以下操作:
class B {
public:
A& GetA (int index) { return GetA_impl(index); }
const A& GetA (int index) const { return GetA_impl(index); }
private:
A& GetA_impl (int index) const { return *(m_C[m_AtoC[i]]); }
};
我不确定在这种情况下确实值得付出努力,但如果可能重复的代码变得更复杂,这可能很有用。
答案 2 :(得分:1)
您可以通过一些模板元编程来避免使用const_cast。
// This meta function returns a const U if T is const, otherwise returns just U.
template <typename T, typename U>
make_same_const<T, U>
{
typedef typename std::conditional<
std::is_const<T>::value,
typename std::add_const<U>::type,
U
>::type type;
};
// Generic version of a function. Constness of return type depends on
// constness of T.
// This is a static member template of B.
template <typename T>
make_same_const<T, A>::type& B::GetA(T& obj, int i)
{
return *(obj.m_C[obj.m_AtoC[i]]);
}
A& B::GetA(int i) { return B::GetA(*this, i); }
A const& B::GetA(int i) const { return B::GetA(*this, i); }
答案 3 :(得分:0)
怎么样
const A &B::GetA (int index) const
{
return *(const_cast<B*>(this)->GetA(index));
}
答案 4 :(得分:0)
IMO这个代码(或复杂性)不足以进行重复数据删除。
正如您在基于const_cast
的解决方案中所看到的,转换表达式实际上更长而不是原始代码。
如果你有一个更长或更复杂的表达,你真的很担心,但请展示它。
答案 5 :(得分:0)
假设GetA()
和GetA() const
的正文相同(这意味着GetA()
不会修改*this
),您可以安全地使用一个const_cast
来const A& B::GetA() const {
return const_cast<B*>(this)->GetA();
}
使用非const的实现const版本:
GetA()
非const const B
不会修改对象,因此在GetA()
对象上调用它不是未定义的。非const const&
返回的非const引用在返回GetA() const
之前转换为{{1}},因此也没有未定义行为的危险。