我最近发现了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没有'operator =()'函数接受类型为wchar_t * '的参数(或-非常接近-表示此含义的单词)。经过大量研究后,我了解到这是因为即使是派生类的自动编译器生成的
operator=
成员函数也会覆盖从其父类继承的那些成员函数。这似乎违反直觉,并且用户对我很友好。但是,如果我添加
using
关键字:class CStringEx : public CString{
public:
using CString::operator=;
...
};
...子类将现在使用其父类的
operator=
成员函数,一切都很好。到目前为止,一切都很好。但是,在这里和其他地方进一步阅读后,我了解到许多程序员不喜欢将
using
用于此目的。例如,我读过一些评论员,这些评论员描述了潜在的有害副作用,例如从父级中引入ALL operator =。但是,同样,除了在非常特殊的情况下,我不理解为什么继承所有父成员函数会是问题。如果这是主要问题,那么有人可以解释这样做的普遍危险吗?我唯一想到的替代方法是在子类的父类中为的每个
operator=
成员函数写出 stub 函数,然后显式调用这些成员函数: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
关键字呢? 最佳答案
这有点主观,所以让我们回顾一下我们所知道的:
如果using
是适合该工作的工具,则应使用它。说:
using
将始终引入所有父方法/运算符,甚至包括您从未打算添加的新方法/运算符。当某人创建一个与子对象交互不佳的父代赋值运算符时,这甚至可能导致代码损坏。 CStringEx
创建CString
,但这也许是预期的行为。 鉴于您最初是在质疑它(基于您所听到的事情)以及以上几点,因此让我们退后一步,看看您的设计。
CStringEx
有两种可能性:CString
对象(如果必须)上运行的自由函数算法。