I recently discovered a new application of the using
keyword; not with reference to the namespace
functionality but inside a derived class declaration. In my case this was pertinent in regards the issues surrounding the 'operator=' member-function.
I had a situation where, given the declarations:
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.
};
...an object of CStringEx
did not work as I expected:
CStringEx cString;
cString=L"String contents";
Instead a compiler error was generated stating 'CStringEx has no 'operator=()' function that takes an argument of type wchar_t*' (or - very close - words to that effect). After quite a bit of study I learned this is because even the automatically compiler-generated operator=
member-functions of a derived class override those inherited from its parent class. This seems counter-intuitive and user-UNfriendly to me.
However, if I add a using
keyword:
class CStringEx : public CString{
public:
using CString::operator=;
...
};
...the child class will now use its parent's operator=
member function and all is well.
So far, so good. However, after further reading here and elsewhere I have learned that many programmers do not like to utilize using
for this purpose. For instance I have read some commentators who describe potentially unwanted side-effects, such as brining in ALL the operator= from the parent. However, again, other than in very specific circumstances I do not understand why inheriting all the parent member-functions would be and issue. If this is the major concern could someone explain the general dangers of doing so?
The only alternative I can think of is to write out stub functions in the child class for every operator=
member-function of it's parent and then explicitly call those respective member-functions:
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...
};
When compared to the version with using CString::operator=
this looks extremely ugly, cumbersome and messy to me. So again, why not use the using
keyword?