7

我最近发现了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关键字呢?

4

1 回答 1

1

这有点主观,所以让我们回顾一下我们所知道的:

如果using是适合这项工作的工具,那么您应该使用它。那说:

  • using始终引入所有父方法/操作符,甚至是您从未想过的新添加的方法/操作符。当有人创建与子对象交互不佳的父赋值运算符时,这甚至可能导致代码损坏。
  • 引入父级的复制赋值运算符意味着您可以CStringEx从 a 创建 aCString但也许这是预期的行为。
  • 未来的读者/维护者可能不熟悉使用语法的运算符,并且可能会使代码更难理解。

鉴于您最初是在质疑它(基于您所听到的内容)以及以上几点,让我们退后一步,看看您的设计。有CStringEx两种可能:

  1. 它有额外的数据成员。在这种情况下,我愿意断言继承父运算符在某些或所有情况下都会出错,因为子类成员不会在分配中处理。
  2. 它没有额外的数据成员,它只提供额外的代码功能。在这种情况下,请不要试图使用子类。而是编写对(迭代器)范围或对象(如果必须)进行操作的自由函数算法CString
于 2014-10-30T18:53:08.613 回答