我最近发现了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,但这也许是预期的行为。
  • 将来的读者/维护者可能不熟悉使用语法的运算符(operator),并且可能会使代码更难理解。

  • 鉴于您最初是在质疑它(基于您所听到的事情)以及以上几点,因此让我们退后一步,看看您的设计。 CStringEx有两种可能性:
  • 它具有其他数据成员。在这种情况下,我愿意断言在某些或所有情况下继承父运算符都会做错什么,因为子类成员不会在分配中处理。
  • 它没有其他数据成员,仅提供其他代码功能。在这种情况下,请不要试图使用子类。而是编写在(迭代器)范围或CString对象(如果必须)上运行的自由函数算法。
  • 10-02 02:13
    查看更多