我最近发现了using
关键字的一个新应用;不是参考namespace
功能,而是在派生类声明中。就我而言,这与围绕“operator=”成员函数的问题有关。
鉴于声明,我有一种情况:
class CString{
public:
...//Various functions.
operator=(const CString &cString)
{
//code to share internal array and increment reference count
}
operator=(const wchar_t *pstrString)
{
//code to create a personal internal array,
//resize it appropriately and copy the pstrString argument.
}
...
};
class CStringEx : public CString{
...//various members that expand upon CString's abilities.
};
...一个对象CStringEx
没有像我预期的那样工作:
CStringEx cString;
cString=L"String contents";
相反,生成了一个编译器错误,说明“ CStringEx 没有采用 wchar_t* 类型参数的'operator=()' 函数”(或 - 非常接近 - 类似的词)。经过大量研究,我了解到这是因为即使operator=
是派生类的编译器自动生成的成员函数也会覆盖从其父类继承的成员函数。这对我来说似乎违反直觉和用户友好。
但是,如果我添加一个using
关键字:
class CStringEx : public CString{
public:
using CString::operator=;
...
};
...子类现在将使用其父类的operator=
成员函数,一切都很好。
到目前为止,一切都很好。然而,在这里和其他地方进一步阅读后,我了解到许多程序员不喜欢using
为此目的使用。例如,我读过一些评论员,他们描述了可能不需要的副作用,例如从父级中引入所有 operator=。然而,再一次,除了在非常特殊的情况下,我不明白为什么继承所有父成员函数会成为问题。如果这是主要问题,有人可以解释这样做的一般危险吗?
我能想到的唯一选择是在子类中为其父类的每个 成员函数写出存根函数,operator=
然后显式调用这些各自的成员函数:
class CStringEx : public CString{
public:
...
const CStringEx& operator=(const wchar_t* pstrString)
{
CString::operator=(pstrString);
return *this;
}
const CStringEx& operator=(const CString &cString)
{
CString::operator=(cString);
return *this;
}
...//and so on...
};
与这个版本相比,using CString::operator=
这对我来说看起来非常丑陋、繁琐和凌乱。那么,为什么不使用using
关键字呢?