Yes. The simplest method is to declare your variables as protected rather than private:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
class A {
public:
A(int val) : _val(val) {}
protected:
int _val;
};
class B : public A {
public:
B(int val) : A(val) {}
friend std::ostream& operator<<(std::ostream& os, const B& b) {
os << b._val;
return os;
}
};
This isn't a great idea, especially if you want to keep encapsulation, so just giving all your variables protected or public access isn't necessarily a great thing to do. Nevertheless, there are other ways to do it, too, notably providing another print method in the parent class:
class A {
public:
A(int val) : _val(val) {}
friend std::ostream& operator<<(std::ostream& os, const A& a) {
os << a._val;
return os;
}
private:
int _val;
};
class B : public A {
public:
B(int val) : A(val) {}
friend std::ostream& operator<<(std::ostream& os, const B& b) {
os << static_cast<A>(b);
return os;
}
};
Because operators are functions as well, it's just that when you call them, you don't include the parentheses you usually see when you call member functions (or any function, really).
And as with class functions, you have to define them for specific objects in your class, unless your class is POD.
Can someone explain to me how I can fit this into my classes?
I have been searching all of the reference data on the functions to understand it but I cant find it. I would paste my code in here but it is too long character wise.
I specifically do not underatand this part:
class A {
public:
A(int val) : _val(val) {}
friend std::ostream& operator<<(std::ostream& os, const A& a) {
os << a._val;
return os;
}
private:
int _val;
};
class B : public A {
public:
B(int val) : A(val) {}
friend std::ostream& operator<<(std::ostream& os, const B& b) {
os << static_cast<A>(b);
return os;
}
};
Those are initializer lists. It is the recommended way of setting up your variables in your constructor.
To give an idea, these are almost equivalent:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
class C1 {
public:
C1(int val) : _val(val) {}
private:
int _val;
};
class C2 {
public:
C2(int val) {
this->_val = val;
}
private:
int _val;
};
What I have in class B is the initializer list calling As constructor. When you have inheritance with non-default constructors, this is how you pass the variables up to the appropriate constructor.