ABC ostream & operator <<

V

Victor Irzak

Hello,

I have an ABC.
it supports:
ostream & operator <<

I also have a derived class that supports this operator.

How can I call operator << of the base class for derived object??? Is it
at all possible?


Here is an example. The line with // Error comment generates an error:
cannot create and instance of ABC.

TIA


#include <iostream>

using namespace::std;

class ABC {
protected:
int abc_member;
public:
virtual void onDraw() const = 0;
friend ostream & operator << (ostream &os, const ABC & o);
};

inline ostream & operator << (ostream &os, const ABC & o) {
os << "abc_member: " << o.abc_member;
return os;
}

class Derived : public ABC {
double der_member;
public:
Derived() {abc_member = 8; der_member=3.4f;}
virtual void onDraw() const {}
friend ostream & operator << (ostream &os, const Derived & o);
};

inline ostream & operator << (ostream &os, const Derived & o) {
os << "der_member: " << o.der_member;
return os;
}


int main () {
Derived * d = new Derived();
cout << *d << endl;
//cout << (ABC) *d << endl; // Error
return 0;
}
 
S

Stuart Golodetz

Victor Irzak said:
Hello,

I have an ABC.
it supports:
ostream & operator <<

I also have a derived class that supports this operator.

How can I call operator << of the base class for derived object??? Is it
at all possible?


Here is an example. The line with // Error comment generates an error:
cannot create and instance of ABC.

TIA


#include <iostream>

using namespace::std;

class ABC {
protected:
int abc_member;
public:
virtual void onDraw() const = 0;
friend ostream & operator << (ostream &os, const ABC & o);
};

inline ostream & operator << (ostream &os, const ABC & o) {
os << "abc_member: " << o.abc_member;
return os;
}

class Derived : public ABC {
double der_member;
public:
Derived() {abc_member = 8; der_member=3.4f;}
virtual void onDraw() const {}
friend ostream & operator << (ostream &os, const Derived & o);
};

inline ostream & operator << (ostream &os, const Derived & o) {
os << "der_member: " << o.der_member;
return os;
}


int main () {
Derived * d = new Derived();
cout << *d << endl;
//cout << (ABC) *d << endl; // Error
return 0;
}

#include <iostream>
// Prefer not to write "using namespace std;", either qualify everything
explicitly with std::, or write *local* using declarations (or directives,
if necessary).
// Actually, the reason I changed this was because VC++ was (wrongly)
refusing to compile it because the friend declaration wasn't recognised
properly.

class ABC
{
protected:
int abc_member;
public:
virtual void onDraw() const = 0;

friend std::eek:stream& operator<<(std::eek:stream& os, const ABC& o);
};

inline std::eek:stream& operator<<(std::eek:stream& os, const ABC& o)
{
os << "abc_member: " << o.abc_member;
return os;
}

class Derived : public ABC
{
private:
double der_member;
public:
Derived()
: der_member(3.4f) // prefer initialisation to assignment
{
abc_member = 8; // but we can't here, since abc_member is a
member of ABC rather than Derived
}

virtual void onDraw() const {}

friend std::eek:stream& operator<<(std::eek:stream& os, const Derived& o);
};

inline std::eek:stream& operator<<(std::eek:stream& os, const Derived& o)
{
os << "der_member: " << o.der_member;
return os;
}


int main()
{
Derived *d = new Derived; // you didn't need the brackets after
Derived
// Prefer '\n' to std::endl unless you intend to deliberately flush the
stream. There is non-negligible overhead involved in pointless flushing.
std::cout << *d << '\n';
std::cout << *((ABC*)d) << '\n'; // C-style cast
(easier to type)
std::cout << *(static_cast<ABC*>(d)) << '\n'; // C++-style cast
(easier to search for, among other advantages)
delete d;

return 0;
}

You were trying to cast the object when you should have just cast the
pointer.

HTH,

Stuart.
 
J

Jerry Coffin

Hello,

I have an ABC.
it supports:
ostream & operator <<

I also have a derived class that supports this operator.

How can I call operator << of the base class for derived object??? Is it
at all possible?

IMO, it's better to avoid this as a rule. Instead, I'd use vaguely
along these lines:

#include <iostream>

class base {
int base_member;

protected:
virtual std::eek:stream &write(std::eek:stream &os) const {
return os << base_member << "\n";
}

// This only looks like a member function. It's really global.
friend std::eek:stream &operator<<(std::eek:stream &os, base const &b) {
return b.write(os);
}
public:
base(int init = 0) : base_member(init) { }
};

class derived : public base {
int derived_member;

virtual std::eek:stream &write(std::eek:stream &os) const {
base::write(os);
return os << derived_member << "\n";
}
public:
derived(int b_init, int d_init) : base(b_init), derived_member
(d_init) { }
};

#ifdef TEST

int main() {

base &b = *(new derived(0, 1));

std::cout << b;
return 0;
}

#endif

The friend operator<< can't be virtual itself, but because it calls a
virtual function, it invokes either base::write or derived::write,
depending on the type that's actually passed to it. If it was a derived
object, that explicitly calls the base::write to handle whatever the
base needs to do, then it writes out its own members.

At last IMO, the client code is NOT the place to deal with things like
this -- one of the fundamental points of object orientation is that the
object should hide details of its implementation, so this should really
be handled by the object itself (as above) rather than in client code
(as you were trying to do it). Of course, there are a few exceptions to
this kind of rule -- just for an obvious one, it might be reasonable to
print out some things during debugging that you won't under normal
circumstances, and it's often perfectly reasonable for the debugging
and/or testing code to know more about the object than the world at
large is supposed to.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,731
Messages
2,569,432
Members
44,832
Latest member
GlennSmall

Latest Threads

Top