muliple-inheriting two functions with identical signatures
-
Hi all, I was hoping for some advice regarding multiple inheritance. In my application I have two interfaces (abstract classes), ICamera and IOrientation. I also have a class C3DCamera, which inherits from both interfaces:
public class ICamera
{
public:
virtual ~ICamera()
{}virtual ICamera *CreateClone() const = 0;
//...
//rest of ICamera's interface
};public class IOrientation
{
public:
virtual ~IOrientation()
{}//...
//rest of IOrientation's interface
};public class C3DCamera : public ICamera, public IOrientation
{//ICamera implementation
ICamera *CreateClone() const;//...
//rest of C3DCamera's declaration
}Now, I need to modify IOrientation's interface by adding a
IOrientation *CreateClone() const
method, but of course I can't because C3DCamera can't have two methods with the same signature. I was hoping I could dis-ambiguate between the two like you can with interface method implementations in C#, but it seems you can't (right?). So what I'm looking for is some advice on what the best way to proceed is. I need both interfaces to expose some form ofCreateClone()
functionality, so that clients can create local copies of classes that implement those interface. Here are the options I see:- simply rename the interfaces' methods to CreateICameraClone(), CreateIOrientationClone, etc.
- Use the technique I read about in Item 43 of Effective C++ - create CCamera and COrientation classes that declare pure virtual CreateICameraClone()/CreateIOrientationClone() methods and define a n overrideable default implementation of CreateClone which calls the appropriate pure virtual method
- ????
Option 1 would be the simplest, but seems a little messy to me. Option 2 is the 'recommended approach', I guess, but seems a little forced. Anyone have any other options, or advice in general? TIA, Pete
Perhaps define a new interface
ICloneable
?ICamera
andIOrientation
would also need to derive from a common class (eg:IImagingLibObject
). This is how Java does it. /ravi My new year's resolution: 2048 x 1536 Home | Articles | Freeware | Music ravib@ravib.com -
Does http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/vcrefexplicitoverrides.asp[^] help? [edit] @%#& you Firefox, why can't you form proper clicketies??? [/edit]
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03 "Obviously ??? You're definitely a superstar!!!" mYkel - 21 Jun '04 Within you lies the power for good - Use it!
Honoured as one of The Most Helpful Members of 2004
Thanks for the reply PJ, I appreciate it. I'm surprised, I didn't think this was possible in C++. Do you know if this is Microsoft-specific? I couldn't find anything about non-Visual C++ explicit overrides anywhere. It also seems that the base classes have to be declared as an __interface, which is MS-specific. If I had a choice I'd rather avoid doing anything non-standard, especially when it seems that porting to another compiler would involve re-designing the class architecture of the application, as opposed to re-writing method implementations, etc. Cheers, Pete
-
Perhaps define a new interface
ICloneable
?ICamera
andIOrientation
would also need to derive from a common class (eg:IImagingLibObject
). This is how Java does it. /ravi My new year's resolution: 2048 x 1536 Home | Articles | Freeware | Music ravib@ravib.comHi Ravi, thanks for the reply. I think maybe I'm misunderstanding, but I think you're saying I should perhaps do something like:
class IClonable
{
public:
virtual ~IClonable()
{}virtual IClonable *CreateClone() = 0;
};class ICamera : public ICloneable
{
//...
};class IOrientation : public ICloneable
{
//...
};class C3DCamera : public ICamera, public IOrientation
{
public:
//...
ICloneable *CreateClone();
}Is that correct? So in this scheme clients of IClonable would presumably be static_cast<>ing the result of CreateClone()? Sounds sensible to me. I'm vaguely worried about the whole 'Diamond Inheritance Considered Evil' thing, but from my understanding (which I admit isn't great), the evilness doesn't apply to abstract base classes, right? One final thing. You mention creating a common IImagingLibObject interface. I don't understand the reason for doing that. Again, thanks for the advice! Pete
-
You can explicitly say which object's implementation you're overriding:
public class C3DCamera : public ICamera, public IOrientation
{//ICamera implementation
ICamera *ICamera::CreateClone() const;//IOrientation implementation
IOrientation *IOriendtation::CreateClone() const;//...
//rest of C3DCamera's declaration
}Hope this helps
Ryan
"Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
-
Hi all, I was hoping for some advice regarding multiple inheritance. In my application I have two interfaces (abstract classes), ICamera and IOrientation. I also have a class C3DCamera, which inherits from both interfaces:
public class ICamera
{
public:
virtual ~ICamera()
{}virtual ICamera *CreateClone() const = 0;
//...
//rest of ICamera's interface
};public class IOrientation
{
public:
virtual ~IOrientation()
{}//...
//rest of IOrientation's interface
};public class C3DCamera : public ICamera, public IOrientation
{//ICamera implementation
ICamera *CreateClone() const;//...
//rest of C3DCamera's declaration
}Now, I need to modify IOrientation's interface by adding a
IOrientation *CreateClone() const
method, but of course I can't because C3DCamera can't have two methods with the same signature. I was hoping I could dis-ambiguate between the two like you can with interface method implementations in C#, but it seems you can't (right?). So what I'm looking for is some advice on what the best way to proceed is. I need both interfaces to expose some form ofCreateClone()
functionality, so that clients can create local copies of classes that implement those interface. Here are the options I see:- simply rename the interfaces' methods to CreateICameraClone(), CreateIOrientationClone, etc.
- Use the technique I read about in Item 43 of Effective C++ - create CCamera and COrientation classes that declare pure virtual CreateICameraClone()/CreateIOrientationClone() methods and define a n overrideable default implementation of CreateClone which calls the appropriate pure virtual method
- ????
Option 1 would be the simplest, but seems a little messy to me. Option 2 is the 'recommended approach', I guess, but seems a little forced. Anyone have any other options, or advice in general? TIA, Pete
The signatures differ by return type - which isn't the same, nor is it different enough. Why are they virtual, what behaviour are you expecting ? How are you planning on using the CreateClone() method(s). What Ryan and PJ suggest is similar to what is described in the ARM 10.1.1. If you read ARM 10.1, 10.2, 10.3 i'm sure you'll be able to figure out a soultion. ...cmk Save the whales - collect the whole set
-
The signatures differ by return type - which isn't the same, nor is it different enough. Why are they virtual, what behaviour are you expecting ? How are you planning on using the CreateClone() method(s). What Ryan and PJ suggest is similar to what is described in the ARM 10.1.1. If you read ARM 10.1, 10.2, 10.3 i'm sure you'll be able to figure out a soultion. ...cmk Save the whales - collect the whole set
Hi, thanks for the reply. The reason they're virtual is pretty much standard interface inheritance. Instead of clients using a C3DCamera instance directly, they will use it's ICamera interface. I need the clients to not expect a C3DCamera, as I'm extending my application with another class (C2DCamera) that can provide ICamera functionality, but NOT IOrientation. Clients that only use the ICamera interface should be able to use either C2DCamera or C3DCamera interchangably. Does that make sense? I need both interfaces to expose a CreateClone() method because clients of both interfaces need to be able to make local copies of the instance that's implementing, without knowing the concrete type of the instance. Unforunately I don't have a copy of ARM at my current workplace. It's not available online, AFAIK. I'll have to bug my boss for a copy, I know it's kinda the bible for C++. Thanks again for the response, Pete
-
Hi, thanks for the reply. The reason they're virtual is pretty much standard interface inheritance. Instead of clients using a C3DCamera instance directly, they will use it's ICamera interface. I need the clients to not expect a C3DCamera, as I'm extending my application with another class (C2DCamera) that can provide ICamera functionality, but NOT IOrientation. Clients that only use the ICamera interface should be able to use either C2DCamera or C3DCamera interchangably. Does that make sense? I need both interfaces to expose a CreateClone() method because clients of both interfaces need to be able to make local copies of the instance that's implementing, without knowing the concrete type of the instance. Unforunately I don't have a copy of ARM at my current workplace. It's not available online, AFAIK. I'll have to bug my boss for a copy, I know it's kinda the bible for C++. Thanks again for the response, Pete
Then you may want to make the return type an argument instead. e.g.
class ICamera {
public:
virtual bool CreateClone( ICamera* &C ) const = 0;
virtual bool f() = 0;
};class IOrientation {
public:
virtual bool CreateClone( IOrientation* &O ) const = 0;
virtual bool f() = 0;
};class C2DCamera : public ICamera, public IOrientation {
public:
virtual bool CreateClone( ICamera* &C ) const { C = new C2DCamera; return(true); }
virtual bool CreateClone( IOrientation* &O ) const { O = new C2DCamera; return(true); }
virtual bool f() { return(true); }
};class C3DCamera : public ICamera, public IOrientation {
public:
virtual bool CreateClone( ICamera* &C ) const { C = new C3DCamera; return(true); }
virtual bool CreateClone( IOrientation* &O ) const { O = new C3DCamera; return(true); }
virtual bool f() { return(true); }
};int main(int argc, char* argv[])
{
C2DCamera d2;
C3DCamera d3;
ICamera *i2 = &d2,
*i3 = &d3;
ICamera *c2 = NULL,
*c3 = NULL;i2->CreateClone(c2); c2->f(); i3->CreateClone(c3); c3->f(); return 0;
}
...cmk
Save the whales - collect the whole set
-
Hi Ryan, thanks for the reply. I could well be wrong, but I was under the impression that the code you gave wasn't valid standard C++. If possible, could you point me towards something that describes this syntax? Cheers, Pete
As far as I know, this is standard syntax. PJ's page above describes it, but I can't recall any other references off the top of my head. Microsoft's documentation is pretty good. It usually states very clearly if they're describing something that is specific to their implementation. Sorry I can't be of more help. Try compiling a simple example with GCC or something like that. If it works there as well, it's probably standard.
Ryan
"Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
-
Then you may want to make the return type an argument instead. e.g.
class ICamera {
public:
virtual bool CreateClone( ICamera* &C ) const = 0;
virtual bool f() = 0;
};class IOrientation {
public:
virtual bool CreateClone( IOrientation* &O ) const = 0;
virtual bool f() = 0;
};class C2DCamera : public ICamera, public IOrientation {
public:
virtual bool CreateClone( ICamera* &C ) const { C = new C2DCamera; return(true); }
virtual bool CreateClone( IOrientation* &O ) const { O = new C2DCamera; return(true); }
virtual bool f() { return(true); }
};class C3DCamera : public ICamera, public IOrientation {
public:
virtual bool CreateClone( ICamera* &C ) const { C = new C3DCamera; return(true); }
virtual bool CreateClone( IOrientation* &O ) const { O = new C3DCamera; return(true); }
virtual bool f() { return(true); }
};int main(int argc, char* argv[])
{
C2DCamera d2;
C3DCamera d3;
ICamera *i2 = &d2,
*i3 = &d3;
ICamera *c2 = NULL,
*c3 = NULL;i2->CreateClone(c2); c2->f(); i3->CreateClone(c3); c3->f(); return 0;
}
...cmk
Save the whales - collect the whole set
Hi, That'll work! I think I'll implement the CreateClone(...) methods as you suggest. A shame that standard C++ won't let you explicitly override a specific base class's pure virtual, but that's life I guess. I'm sure there's a good (and suitably obscure) reason for it. Cheers, Pete
-
As far as I know, this is standard syntax. PJ's page above describes it, but I can't recall any other references off the top of my head. Microsoft's documentation is pretty good. It usually states very clearly if they're describing something that is specific to their implementation. Sorry I can't be of more help. Try compiling a simple example with GCC or something like that. If it works there as well, it's probably standard.
Ryan
"Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
Hi Ryan, Unfortunately I don't have GCC - or anything other than VC++ - available for testing. My reading of the page that PJ gave is that the base classes have to be declared as
interface
or__interface
, which is an MS-specific extension. I have a feeling it was introduced to make Managed C++ a little easier - .NET obviously distinguishes between interfaces and abstract base classes. Thanks a lot for the help anyway, Pete