适用于派生类的C ++中的'Using'关键字

时间:2014-10-30 17:28:46

标签: c++ inheritance using-declaration

我最近发现了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=成员函数也会覆盖从其父类继承的那些成员函数。这似乎违反直觉,用户 - UN 对我友好。

但是,如果我添加using关键字:

class CStringEx : public CString{
public:
    using CString::operator=;
    ...
};

......子类 现在会使用其父级的operator=成员函数,一切都很顺利。

到目前为止,这么好。但是,在这里和其他地方进一步阅读之后,我了解到许多程序员不喜欢为此目的使用using。例如,我已经阅读了一些评论员,他们描述了可能不需要的副作用,例如从父母那里获取所有运算符=。但是,除了在非常具体的情况下,我不明白为什么继承所有父成员函数会是和问题。如果这是主要问题,有人可以解释这样做的一般危险吗?

我能想到的唯一选择是在子类中为其父每个 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关键字?

1 个答案:

答案 0 :(得分:1)

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

如果using是正确的工作工具,那么您应该使用它。那说:

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

鉴于您最初(基于您已经听过的内容)以及上述要点对其进行质疑,让我们退一步看看您的设计。 CStringEx有两种可能性:

  1. 它有其他数据成员。在这种情况下,我愿意断言继承父操作符会在某些或所有情况下做错,因为子类成员不会在作业中处理。
  2. 它没有其他数据成员,它只提供其他代码功能。在这种情况下,请不要试图使用儿童班。而是编写在(迭代器)范围内运行的自由函数算法,或者如果必须,编写CString个对象。