Over the last year I’ve gotten a lot of benefit out of my effort to move to C++. Classes rock!
However, I now am at a point where I don’t understand how the language works, and I’m having trouble finding references to explain. I’m not looking for suggestions of languages that do it better for this; I simply would like an explanation/pointer to information/search term that tells me what to google for in the following issue:
I have a base class and a derived class. The only difference in the derived class is that it has an additional data member and functions which help to access that data member. The important part of my code is as follows:
class Base
{
private:
string Str;
double A;
public:
// ...
friend std::istream& operator>>(std::istream &In, Base &BaseIn)
{
In >> Str >> A;
return In;
}
};
class Derived:Base
{
private:
double B;
public:
// ...
friend std::istream& operator>>(std::istream &In, Derived &DerivedIn)
{
--> In >> Str >> A >> B;
return In;
}
};
The problem I’m having is that if I understand correctly, I can’t override the input operator for the derived class in that way, because I don’t have access to Str and A within the Derived class since they’re private. I could declare them protected to get around this, I believe. Is that the “proper” way to manage this problem? If so it tends to imply that I’ll always need to make base classes protected instead of private, which leads to the question of why does private work the way it does for inherited classes in the first place.
Since I don’t believe they’d have an entire useless provision for data protection (private vs. protected), I’m guessing I’m missing something. I know I can set up functions in the base class that let me manipulate the member data from an external interface and change the overloaded input operator in the derived class to work that way:
class Base
{
private:
// ... See Above
public:
Base& SetStr(const string& _Str) { Str = _Str; return *this; }
Base& SetA(const double& _A) { A = _A; return*this; }
//...
};
class Derived:Base
{
private:
double B;
public:
// ...
friend std::istream& operator>>(std::istream &In, Derived &DerivedIn)
{
string Str;
double A;
double _B;
In >> Str >> A >> _B;
DerivedIn.SetStr(Str);
DerivedIn.SetA(A);
B=_B;
return In;
}
};
However that seems needlessly complex. Is this the proper way? Will this work at all?
Ultimately it feels like it ought to work something like this:
class Derived:Base
{
public:
// ...
private:
// ...
friend std::istream& operator>>(std::istream &In, Derived &DerivedIn)
{
In Base::operator>> DerivedIn >> B;
return In;
}
};
i.e. I should be able to explicitly call the Base version of the input operator >> .
This is how it would work if it were a regular function (Derived::Fn() --> Base::Fn() + excess Fn() processing specific to Derived), but because operator>> is a bit weird I’m not sure I totally understand it and what it actually binds to. (Generally things like Class::Operator+ bind to the lhs, which would imply that what I’d need in the above example would be istream::operator>>, but of course that lhs + operator can’t differentiate between what I’m spitting data into, so that can’t be the answer either.)
Hopefully this somewhat muddled question makes sense to someone out there? I’m fine to do the research if it’s as complex as I’m afraid it might be (Stroustrup’s book gives a great example of calling, say, Base::print() from Derived::print() to operate with the base class’s defined functions, but the istream input operator seems to be logically different here…) if someone can just point me to the proper term for research.
Thanks in advance!