473,322 Members | 1,523 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,322 software developers and data experts.

Problem with covariant return types

I originally thought this was a compiler error but it seems the standard
prohibits the code below. Has anyone got any good ideas about how to code
around it?

class A;
class B;
class X;
class Y;

class X
{
public:

virtual A* g () const;
};

class Y : public X
{
public:

virtual B* g () const;
};

[The compiler signals an error (non-covariant return types) at this point
because it doesn't know that B is derrived from A]

class A
{
public:

virtual X* f () const;
};
class B : public A
{
public:

virtual Y* f () const;
};

Thanks,

Rob.
Jul 22 '05 #1
9 1416
* Rob.:

I originally thought this was a compiler error but it seems the standard
prohibits the code below. Has anyone got any good ideas about how to code
around it?

class A;
class B;
class X;
class Y;

class X
{
public:

virtual A* g () const;
};

class Y : public X
{
public:

virtual B* g () const;
};

[The compiler signals an error (non-covariant return types) at this point
because it doesn't know that B is derrived from A]

class A
{
public:

virtual X* f () const;
};
class B : public A
{
public:

virtual Y* f () const;
};

Off the cuff:
class A;
class B;
class X;
class Y;

class X
{
public:
virtual A* g() const;
A* gA() const;
};

class Y : public X
{
public:
virtual A* g() const;
B* gB();
};
class A
{
public:
virtual X* f() const;
X* fX() const;
};
class B : public A
{
public:
virtual X* f() const;
Y* fY();
};
A* X::gA() const { return g(); }
B* Y::gB() const { return static_cast<B*>( g() ); }
X* A::fX() const { return f(); }
Y* B::fY() const { return static_cast<Y*>( f() ); }

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #2
On Sat, 26 Jun 2004 09:57:41 +0300, "Rob." <ro****@xxx.fi> wrote:
I originally thought this was a compiler error but it seems the standard
prohibits the code below. Has anyone got any good ideas about how to code
around it?

[snip]

What compiler is it? MSVC 6.0, for example, did not yet support
covariant return types IIRC. It supports them in version 7.x, however.

--
Bob Hairgrove
No**********@Home.com
Jul 22 '05 #3
"Alf P. Steinbach" <al***@start.no> wrote in message
class X
class Y : public X class A
{
public:
virtual X* f() const;
X* fX() const;
};
class B : public A
{
public:
virtual X* f() const;
Y* fY();
};
A* X::gA() const { return g(); }
B* Y::gB() const { return static_cast<B*>( g() ); }
X* A::fX() const { return f(); }
Y* B::fY() const { return static_cast<Y*>( f() ); }


This is a great idea. One can use it for user types. Say the base class
returns a shared_ptr<X> and the derived class returns a shared_ptr<Y>, which
we know is covariant but the compiler doesn't.

Only thing I've done in the past is to to rename fX() and fY() to f(). So
my class looks like this:

class A
{
private/protected:
virtual X* dof() const;
public:
counted_ptr<X> f() const { return dof(); }
};

class B : public A
{
private/protected:
virtual X* dof() const;
public:
counted_ptr<Y> f() const { return static_cast<Y*>(dof()); }
};

But wait a sec. I've violated the guideline that you ought not to override
a non-virtual function. In general, this is a fine rule that we ought to
respect. Because when we call a function from a pointer to the base class,
the system ought to call the derived class function -- and the most popular
example of this is the virtual destructor.

But in the above class design, we are calling the derived class function,
namely dof(). It's just that A::f() casts the return type to something
class A knows about, namely an X* or counted_ptr<X>. Presumably A.h
includes X.h or forward declares class X. And B::f() also calls the derived
class function, namely dof() again. Assuming B::dof() returns an object
that is Y or higher cast as an X*, it's perfectly OK for B::f() to cast this
to a counted_ptr<Y>. It's the same object after all.

So when we follow the above idiom, it seems perfectly OK to break the
guideline that you ought not to override a non-virtual function. Any
thoughts?
Jul 22 '05 #4
Rob. posted:
I originally thought this was a compiler error but it seems the standard
prohibits the code below. Has anyone got any good ideas about how to code
around it?

class A;
class B;
class X;
class Y;


Have you tried:

class A;
Class B : public A;
class X;
class Y : public X;

?

-JKop
Jul 22 '05 #5
"JKop" <NU**@NULL.NULL> wrote in message news:5ybDc.3208
Have you tried:

class A;
Class B : public A;
Above line is a syntax error (except in posts we know what you mean).
class X;
class Y : public X;


Signing off for the night...
Jul 22 '05 #6
On Sat, 26 Jun 2004 09:57:41 +0300, "Rob." <ro****@xxx.fi> wrote:
I originally thought this was a compiler error but it seems the standard
prohibits the code below. Has anyone got any good ideas about how to code
around it?

class A;
class B;
class X;
class Y;

class X
{
public:

virtual A* g () const;
};

class Y : public X
{
public:

virtual B* g () const;
};

[The compiler signals an error (non-covariant return types) at this point
because it doesn't know that B is derrived from A]

class A
{
public:

virtual X* f () const;
};
class B : public A
{
public:

virtual Y* f () const;
};

Thanks,

Rob.


I don't think this will work because of the implicit circular
reference(s) you have. You might try just returning a pointer to the
base class in each instance.

--
Bob Hairgrove
No**********@Home.com
Jul 22 '05 #7

"JKop" <NU**@NULL.NULL> wrote in message
news:5y*****************@news.indigo.ie...
Rob. posted:
I originally thought this was a compiler error but it seems the standard
prohibits the code below. Has anyone got any good ideas about how to code around it?

class A;
class B;
class X;
class Y;


Have you tried:

class A;
Class B : public A;
class X;
class Y : public X;

?

-JKop


Yes I've tried that. Thought it might be possible to tell the compiler that
B was derived from A before fully defining the class. Apparently not (well
not in msvc 7.1 a least).

Thanks,

Rob.
Jul 22 '05 #8
* Siemel Naran:
"Alf P. Steinbach" <al***@start.no> wrote in message
class X
class Y : public X

class A
{
public:
virtual X* f() const;
X* fX() const;
};
class B : public A
{
public:
virtual X* f() const;
Y* fY();
};
A* X::gA() const { return g(); }
B* Y::gB() const { return static_cast<B*>( g() ); }
X* A::fX() const { return f(); }
Y* B::fY() const { return static_cast<Y*>( f() ); }


This is a great idea.


Now that I'm awake: actually for type safety the calls should go the
other way, e.g. Y::g should invoke Y::gB, with no casts.

Am I stupid, or what?

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #9
* Alf P. Steinbach:

Now that I'm awake: actually for type safety the calls should go the
other way, e.g. Y::g should invoke Y::gB, with no casts.

Am I stupid, or what?


Yes, definitely; I had it right the first time. Grr. And now I'm
holding a conversation with myself...

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Alex Vinokur | last post by:
Hello, Here is some program with virtual constructors. Is there any difference between * clone1() vs. clone2() * create1() vs. create2() ? It seems that it should be.
3
by: Sankar Nemani | last post by:
Hi, Does anyone know what the reason behind not allowing to use "covariant return types when overriding methods in derived classes" in C# is? Also while other OO languages such as Java, don't...
14
by: Stefan Slapeta | last post by:
Hi, this code does not compile in C#: class base_class {} class derived_class : base_class {} class A { public virtual base_class f()
13
by: Stephen Walch | last post by:
Error C2392 is hitting me hard! I have a managed C++ library that implements a bunch of fixed interfaces. For example, one interface is: public abstract interface IDbCommand { public...
2
by: Edward Diener | last post by:
In C++ an overridden virtual function in a derived class must have the exact same signature of the function which is overridden in the base class, except for the return type which may return a...
16
by: Bob Hairgrove | last post by:
Consider the classic clone() function: class A { public: virtual ~A() {} virtual A* clone() const = 0; }; class B : public A { public:
6
by: miked | last post by:
Why are there still no covariant return types? All searches reveal no workarounds accept for using an interface which is a real pain. I wind up missing this capability almost every time I...
8
by: Alex Vinokur | last post by:
Here is a code from http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.8 -------------------------------------- class Shape { public: virtual ~Shape() { } // A...
3
by: kikazaru | last post by:
Is it possible to return covariant types for virtual methods inherited from a base class using virtual inheritance? I've constructed an example below, which has the following structure: Shape...
9
by: Rahul | last post by:
Hi Everyone, I was trying to implement covariant return types and i get a compilation error, class BB : public AA { }; class A
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.