Login or Sign up Help | Site Map
Connecting Tech Pros Worldwide

forward declaration & virtual member function return derived class

Question posted by: kepeng@gmail.com (Guest) on July 2nd, 2008 05:55 PM
There are 2 abstract base classes:

class IB;
class IA
{
//...
public:
virtual IB* GetB() = 0;
}

class IB
{
//...
public:
virtual IA* GetA() = 0;
}

Then, this is derived classes:

class CB; //#1
class CA : public IA
{
//...
public:
CB* GetB(); //#2
}
class CB : public IB
{
//...
public:
CA* GetA(); //#3
}

The question is, the declaration do not work.
In C++, the overrided function can return a class which is public
derived from the return type of the function in base class.
When the function #2 returns IB*, it is OK. #3 is OK, too.
But, when #2 returns CB*, the compiler says something like "CB is not
derived from IB".
At #1, I can not declare like this:
class CB : public IB;
The syntax is not passed.

So, what can I do?
There is cycle dependence, but I do not care of the dependence: CA and
CB is almost in a single .cpp file.
Would you like to answer this question?
Sign up for a free account, or Login (if you're already a member).
.rhavin grobert's Avatar
.rhavin grobert
Guest
n/a Posts
July 2nd, 2008
06:05 PM
#2

Re: forward declaration & virtual member function return derived class
On 2 Jul., 19:46, "kep...@gmail.com" <kep...@gmail.comwrote:
Quote:
Originally Posted by
There are 2 abstract base classes:
>
class IB;
class IA
{
//...
public:
virtual IB* GetB() = 0;
>
}
>
class IB
{
//...
public:
virtual IA* GetA() = 0;
>
}
>
Then, this is derived classes:
>
class CB; //#1
class CA : public IA
{
//...
public:
CB* GetB(); //#2}
>
class CB : public IB
{
//...
public:
CA* GetA(); //#3
>
}
>
The question is, the declaration do not work.
In C++, the overrided function can return a class which is public
derived from the return type of the function in base class.
When the function #2 returns IB*, it is OK. #3 is OK, too.
But, when #2 returns CB*, the compiler says something like "CB is not
derived from IB".
At #1, I can not declare like this:
class CB : public IB;
The syntax is not passed.
>
So, what can I do?
There is cycle dependence, but I do not care of the dependence: CA and
CB is almost in a single .cpp file.


you need to give them different names, because you cant overload a
function by just changing it's return-type:

class CB : public IB
{
public:
CA* _GetA() {return static_cast<CA*>(GetA());};
private:
IA* GetA();
};

gw7rib@aol.com's Avatar
gw7rib@aol.com
Guest
n/a Posts
July 2nd, 2008
08:05 PM
#3

Re: forward declaration & virtual member function return derived class
On 2 Jul, 18:46, "kep...@gmail.com" <kep...@gmail.comwrote:
Quote:
Originally Posted by
class IA
{
* * //...
public:
* * virtual IB* GetB() = 0;
}
>
class CA : public IA
{
* * //...
public:
* * CB* GetB(); //#2}


Your problem, as rhavin grobert has also pointed out, is that in one
case GetB returns an IB* and in the other it returns a CB*. He has
suggested you use functions with different names, but that doesn't
seem to me to be quite what you want. I think you need to decide
whether GetB will return a CB* for all classes derived from IA, or
not. If you're always going to return a CB* then change the
declaration in IA. If not, change the declaration in class IA so that
it says GetB returns an IB*. Since CB is derived from IB, a pointer to
an IB can hold any value that a pointer to a CB can, so the values can
be passed quite happily.

If you really need the return type of GetB to be different for
different classes, you may need to have differently-named functions,
or to have another think about your class structure.

Hope that helps.
Paul.

Jonathan Mcdougall's Avatar
Jonathan Mcdougall
Guest
n/a Posts
July 2nd, 2008
08:45 PM
#4

Re: forward declaration & virtual member function return derived class
On Jul 2, 1:46 pm, "kep...@gmail.com" <kep...@gmail.comwrote:
Quote:
Originally Posted by
There are 2 abstract base classes:
>
class IB;
class IA
{
//...
public:
virtual IB* GetB() = 0;
>
}
>
class IB
{
//...
public:
virtual IA* GetA() = 0;
>
}
>
Then, this is derived classes:
>
class CB; //#1
class CA : public IA
{
//...
public:
CB* GetB(); //#2}
>
class CB : public IB
{
//...
public:
CA* GetA(); //#3
>
}
>
The question is, the declaration do not work.


You are missing semicolons at the end of the class definitions. Test
your
code before posting it.
Quote:
Originally Posted by
In C++, the overrided function can return a class which is public
derived from the return type of the function in base class.
When the function #2 returns IB*, it is OK. #3 is OK, too.
But, when #2 returns CB*, the compiler says something like "CB is not
derived from IB".
At #1, I can not declare like this:
class CB : public IB;
The syntax is not passed.


As far as I can tell, you cannot use covariance in this case. Either
return a
pointer to the interface or change your design so that you do not have
a
cyclic dependency.

--
Jonathan Mcdougall

acehreli@gmail.com's Avatar
acehreli@gmail.com
Guest
n/a Posts
July 3rd, 2008
03:05 AM
#5

Re: forward declaration & virtual member function return derived class
On Jul 2, 11:04 am, ".rhavin grobert" <cl...@yahoo.dewrote:
Quote:
Originally Posted by
On 2 Jul., 19:46, "kep...@gmail.com" <kep...@gmail.comwrote:
>
>
>
Quote:
Originally Posted by
There are 2 abstract base classes:

>
Quote:
Originally Posted by
class IB;
class IA
{
//...
public:
virtual IB* GetB() = 0;

>
Quote:
Originally Posted by
}

[...]
Quote:
Originally Posted by
Quote:
Originally Posted by
class CA : public IA
{
//...
public:
CB* GetB(); //#2}


[...]
Quote:
Originally Posted by
you need to give them different names, because you cant overload a
function by just changing it's return-type:


Yes but this is not overloading. Because of that 'virtual' above, CA
is overriding the same function, and C++ does support covariant return
types.

The problem here is that CA and CB cannot both see the definition of
the other at the same time. It must be possible to solve by returning
proxy classes instead of plain IB* and CB*.

Ali

acehreli@gmail.com's Avatar
acehreli@gmail.com
Guest
n/a Posts
July 3rd, 2008
03:15 AM
#6

Re: forward declaration & virtual member function return derived class
On Jul 2, 10:46*am, "kep...@gmail.com" <kep...@gmail.comwrote:
Quote:
Originally Posted by
There are 2 abstract base classes:
>
class IB;
class IA
{
* * //...
public:
* * virtual IB* GetB() = 0;
>
}
>
class IB
{
* * //...
public:
* * virtual IA* GetA() = 0;
>
}
>
Then, this is derived classes:
>
class CB; //#1
class CA : public IA
{
* * //...
public:
* * CB* GetB(); //#2}
>
class CB : public IB
{
* * //...
public:
* * CA* GetA(); //#3
>
}
>
The question is, the declaration do not work.
In C++, the overrided function can return a class which is public
derived from the return type of the function in base class.
When the function #2 returns IB*, it is OK. #3 is OK, too.
But, when #2 returns CB*, the compiler says something like "CB is not
derived from IB".
At #1, I can not declare like this:
class CB : public IB;
The syntax is not passed.
>
So, what can I do?
There is cycle dependence, but I do not care of the dependence: CA and
CB is almost in a single .cpp file.


Try using proxy classes (Holders below) that allow covariance by being
fully defined where used:


class IA;

class IAHolder
{
IA * ia_;
};

class CA;

class CAHolder : public IAHolder
{
CA * ca_;
};


class IB;

class IBHolder
{
IB * ia_;
};

class CB;

class CBHolder : public IBHolder
{
CB * ca_;
};


class IA
{
//...
public:
virtual ~IA()
{}
virtual IBHolder * GetB() = 0;

};


class IB
{
//...
public:
virtual ~IB()
{}
virtual IAHolder * GetA() = 0;

};


class CB; //#1
class CA : public IA
{
//...
public:
CBHolder * GetB()
{
return 0;
}
};


class CB : public IB
{
//...
public:
CAHolder * GetA()
{
return 0;
}
};

int main()
{
CA ca;
CB cb;
}

Ali

gw7rib@aol.com's Avatar
gw7rib@aol.com
Guest
n/a Posts
July 3rd, 2008
08:05 PM
#7

Re: forward declaration & virtual member function return derived class
On 2 Jul, 20:57, gw7...@aol.com wrote:
Quote:
Originally Posted by
On 2 Jul, 18:46, "kep...@gmail.com" <kep...@gmail.comwrote:
>
Quote:
Originally Posted by
class IA
{
* * //...
public:
* * virtual IB* GetB() = 0;
}

>
Quote:
Originally Posted by
class CA : public IA
{
* * //...
public:
* * CB* GetB(); //#2}

>
Your problem, as rhavin grobert has also pointed out, is that in one
case GetB returns an IB* and in the other it returns a CB*. He has
suggested you use functions with different names, but that doesn't
seem to me to be quite what you want. I think you need to decide
whether GetB will return a CB* for all classes derived from IA, or
not. If you're always going to return a CB* then change the
declaration in IA. If not, change the declaration in class IA so that


My mistake - this should say ... change the declaration in class CA
so that ...
Quote:
Originally Posted by
it says GetB returns an IB*. Since CB is derived from IB, a pointer to
an IB can hold any value that a pointer to a CB can, so the values can
be passed quite happily.
>
If you really need the return type of GetB to be different for
different classes, you may need to have differently-named functions,
or to have another think about your class structure.
>
Hope that helps.
Paul.



 
Not the answer you were looking for? Post your question . . .
182,494 Experts ready to help you find a solution.
Sign up for a free account, or Login (if you're already a member).

  • Didn't find the answer you were looking for?
    Post Your Question
  • Top Community Contributors