By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,132 Members | 1,330 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,132 IT Pros & Developers. It's quick & easy.

ABC ostream & operator <<

P: n/a
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;
}
Jul 19 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a
"Victor Irzak" <vi****@rogers.com> wrote in message
news:3F***************@rogers.com...
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::ostream& operator<<(std::ostream& os, const ABC& o);
};

inline std::ostream& operator<<(std::ostream& 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::ostream& operator<<(std::ostream& os, const Derived& o);
};

inline std::ostream& operator<<(std::ostream& 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.
Jul 19 '05 #2

P: n/a
Yes, that helps.

Thanks for extra comments too!

Victor

Stuart Golodetz wrote:
"Victor Irzak" <vi****@rogers.com> wrote in message
news:3F***************@rogers.com...
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::ostream& operator<<(std::ostream& os, const ABC& o);
};

inline std::ostream& operator<<(std::ostream& 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::ostream& operator<<(std::ostream& os, const Derived& o);
};

inline std::ostream& operator<<(std::ostream& 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.


Jul 19 '05 #3

P: n/a
In article <3F***************@rogers.com>, vi****@rogers.com says...
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::ostream &write(std::ostream &os) const {
return os << base_member << "\n";
}

// This only looks like a member function. It's really global.
friend std::ostream &operator<<(std::ostream &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::ostream &write(std::ostream &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.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 19 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.