473,322 Members | 1,755 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.

Are covariant cyclic dependancies legal?

Jon


struct B2;

struct B1 {
virtual B2* get2() = 0;
};

struct B2 {
virtual B1* get1() = 0;
};

struct D2; //"struct D2 : public B2;" is illegal

struct D1 : public B1 {
virtual D2* get2(); //Can I declare this somehow?
};

struct D2 : public B2 {
virtual D1* get1();
};

Feb 14 '07 #1
4 1108
Jon wrote:
struct B2;

struct B1 {
virtual B2* get2() = 0;
};

struct B2 {
virtual B1* get1() = 0;
};

struct D2; //"struct D2 : public B2;" is illegal

struct D1 : public B1 {
virtual D2* get2(); //Can I declare this somehow?
};

struct D2 : public B2 {
virtual D1* get1();
};
I think it's impossible. You'll have to make either or both
non-covariant. Covariance generally only saves you the odd static_cast
in any case.

Tom
Feb 14 '07 #2
struct B2;
>
struct B1 {
virtual B2* get2() = 0;
};

struct B2 {
virtual B1* get1() = 0;
};

struct D2; //"struct D2 : public B2;" is illegal

struct D1 : public B1 {
virtual D2* get2(); //Can I declare this somehow?
};

struct D2 : public B2 {
virtual D1* get1();
};
I think it's not possible as compiler does not know from the forward
declaration that D2 inherits B2.
--
Vladimir Nesterovsky
Feb 14 '07 #3
Jon wrote:
struct B2;

struct B1 {
virtual B2* get2() = 0;
};

struct B2 {
virtual B1* get1() = 0;
};

struct D2; //"struct D2 : public B2;" is illegal

struct D1 : public B1 {
virtual D2* get2(); //Can I declare this somehow?
};

struct D2 : public B2 {
virtual D1* get1();
};
Very good question.

To the best of my knowledge, the only way to get this to work is to make
B1 a nested class within B2 (or vice versa):

struct B2;

struct B1 {
virtual B2* get2() = 0;
};

struct B2 {
virtual B1* get1() = 0;
};

struct D2; //"struct D2 : public B2;" is illegal

struct D2 : public B2 {

struct D1 : public B1 {
virtual D2* get2(); //Can I declare this somehow?
};

virtual D1* get1();
};

typedef D2::D1 D1;

You have to ask yourself the question if it's worth it, though. It's
quite a bit messy, in my humble opinion. The language purists are going
to raise an eyebrow. It might be worth considering, but you have to
think about maintenance issues in the long run. At least you should very
carefully document it. One will have a hard time understanding the
reason why D1 was embedded inside D2. It doesn't belong there. You can't
extend such a hierarchy easily -- it's quite a big restriction that a
future class D3, for example, can't be implemented in a separate file,
you have to edit the definition of D2 for this. Unless your hierarchy is
already very stable, I would forget about this.

Here's a much cleaner solution:

struct B2;

struct B1 {
virtual B2* get2() = 0;
};

struct B2 {
virtual B1* get1() = 0;
};

struct D2; //"struct D2 : public B2;" is illegal

struct D1 : public B1 {
virtual B2* get2(); //Can I declare this somehow?
inline D2* get2_D();
};

struct D2 : public B2 {
virtual B1* get1();
D1* get1_D() { return static_cast<D1*>(get1()); }
};

D2* D1::get2_D() { return static_cast<D2*>(get2()); }

This might be just slightly less invonvenient to use, but the solution
is more robust, and the API is not subject to any restriction.

This is how things are done when you can't have covariant return types.
Your code is a good example. Another good case is boost::shared_ptr<D1>,
boost::shared_ptr<D2>. There, again, you can't use covariant return
types at all.

There was life before covariant return types were introduced to the
language, and back then people still survived somehow. ;-)

Tom
Feb 14 '07 #4
Tamas Demjen wrote:
the only way to get this to work is to make B1 a nested class within B2:
oops, I meant D1 a nested class within D2.
Feb 14 '07 #5

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

Similar topics

9
by: John Doe | last post by:
Hi all, Regarding those cyclic dependencies of classes (like cases in which class A refers to class B and class B to class A): can they ALL be resolved by forward defining classes, and by...
8
by: Martin Stettner | last post by:
Hi, I would like to use covariant return types in mutual dependent classes like: class IB; class IA { virtual IB* getIB() = 0; }; class IB{ virtual IA* getIA() = 0;
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...
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:
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...
0
by: Kevin Frey | last post by:
Sorry I can't find anything concrete in respect of this: I want a delegate to refer to a method that utilises a covariant return type. I believe this is now legal in .NET 2.0 for C# - what about...
2
by: Sebastian Schucht | last post by:
Hi, I have a templateclass with virtual member-functions, so i can't create instances ... but for returning the result i would like use one. So i replaced the A<TTypefrom the baseclass with the...
3
by: abir | last post by:
Hi, is there any way forward declare a covariant return type (and is it a language feature or extension only)? I have class, class CompModel; class CompWorker{ public: virtual CompModel&...
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...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
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...
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
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
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.