![]() |
| | #1 |
| Registered User Join Date: Jul 2003
Posts: 32
| Multiple inheritance issue I have the following problem when trying to disambiguate the behaviour of a function in the most-derived class: Code: class B
{
public:
virtual void f() {}
};
class C : public B
{
};
class D : public C, public B
{
public:
virtual void f() {C::B::f();} // error: cannot call member function ‘virtual void B::f()’ without object
};
g++ (GCC) 4.2.4 (Ubuntu 4.2.4-1ubuntu3) Thanks!! |
| Helix is offline | |
| | #2 |
| Kernel hacker Join Date: Jul 2007 Location: Farncombe, Surrey, England
Posts: 15,686
| It's the same as this: Code: class A
{
public:
void func();
};
int main()
{
A::func();
}
However, even if you have an object, you are still not going to know which B::f() to call. Why do you want to inherit the same class TWICE, and then call the inner base-class via the first class. Perhaps you actually want to do this: Code: class B
{
public:
virtual void f() {}
};
class C : public B
{
};
class D : public C, public B
{
public:
virtual void f() {
this->C::f();
} // error: cannot call member function ‘virtual void B::f()’ without object
};
-- Mats
__________________ Compilers can produce warnings - make the compiler programmers happy: Use them! Please don't PM me for help - and no, I don't do help over instant messengers. |
| matsp is offline | |
| | #3 | |
| Registered User Join Date: Jul 2003
Posts: 32
| Quote:
And, the compiler should know which B::f() to call specifically because I wrote C::B::f(). So it should call the f() of the B in C. What i'm trying to achieve is logical, and the code too seems logical to me. | |
| Helix is offline | |
| | #4 |
| Kernel hacker Join Date: Jul 2007 Location: Farncombe, Surrey, England
Posts: 15,686
| I'll take your word for that. How about this: Code: class B
{
public:
virtual void f() {}
};
class C : public B
{
public:
virtual void f()
{
this->B::f();
}
};
class D : public C, public B
{
public:
virtual void f() {
this->C::f();
}
};
Mats
__________________ Compilers can produce warnings - make the compiler programmers happy: Use them! Please don't PM me for help - and no, I don't do help over instant messengers. |
| matsp is offline | |
| | #5 |
| Registered User Join Date: Jul 2003
Posts: 32
| Hmm, I see that in my original example writing C::f() instead of C::B::f() works, and the effect is the same. But how do I invoke D::B::f() ? Now I want to call the implementation of f() in the B that is the direct superclass of D. Reposting the problematic code. Code: class B
{
public:
virtual void f() {}
};
class C : public B
{
};
class D : public C, public B
{
public:
virtual void f() {B::f();} // error: cannot call member function ‘virtual void B::f()’ without object
};
Last edited by Helix; 03-31-2009 at 05:49 AM. |
| Helix is offline | |
| | #6 |
| Registered User Join Date: Jun 2005
Posts: 1,438
| The call D::B::f(), no matter how you specify it, is ambiguous unless B is a virtual base. So the call is not possible. Your design may be clear in your mind, but that's not the same as saying it is a good design. Try giving a hint about what you're trying to do; someone may then be able to provide an alternative that can actually be implemented realistically in C++. |
| grumpy is offline | |
| | #7 |
| Kernel hacker Join Date: Jul 2007 Location: Farncombe, Surrey, England
Posts: 15,686
| And beside from being able to implement it, maybe it will also be possible to maintain and modify later on without having a nightmare of knowing which f() is being called when and where. -- Mats
__________________ Compilers can produce warnings - make the compiler programmers happy: Use them! Please don't PM me for help - and no, I don't do help over instant messengers. |
| matsp is offline | |
| | #8 | |
| Registered User Join Date: Jul 2003
Posts: 32
| Quote:
I'm not convinced that this call shouldn't be possible. It says in the Standard (10.2.5) that for nonvirtual base classes one uses explicit qualification (an inheritance path) to specify which sub-object is meant. I've seen this exemplified with fields, but it should work with functions. Furthermore: I was not *very* suprised to see that Visual Studio compiles and calls the implementation of f() that I would expect! If you wanna try it: Code: class B
{
public:
char mC;
B(char c) : mC(c) {}
virtual char f() {return mC;}
};
class C : public B
{
public:
C() : B('C') {}
virtual char f() {return 'A';}
};
class D : public C, public B
{
public:
D() : C(), B('D') {}
virtual char f() {return B::f();} // error: cannot call member function ‘virtual void B::f()’ without object
};
Code: void main() { std::cout<<D().f();
}
| |
| Helix is offline | |
| | #9 |
| Kernel hacker Join Date: Jul 2007 Location: Farncombe, Surrey, England
Posts: 15,686
| Visual Studio is NOT a good measure of "standards comliance". gcc makes much more of an effort to comply with standards and being correct. -- Mats
__________________ Compilers can produce warnings - make the compiler programmers happy: Use them! Please don't PM me for help - and no, I don't do help over instant messengers. |
| matsp is offline | |
| | #10 |
| Registered User Join Date: Jul 2003
Posts: 32
| |
| Helix is offline | |
| | #11 | |
| Kernel hacker Join Date: Jul 2007 Location: Farncombe, Surrey, England
Posts: 15,686
| Quote:
-- Mats
__________________ Compilers can produce warnings - make the compiler programmers happy: Use them! Please don't PM me for help - and no, I don't do help over instant messengers. | |
| matsp is offline | |
| | #12 | ||
| Cat without Hat Join Date: Apr 2003
Posts: 8,492
| Quote:
Quote:
I cannot think of a situation where broken triangle inheritance is ever the right solution for anything. Can you give us a few concrete hints about your design?
__________________ All the buzzt! CornedBee"There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code." - Flon's Law Last edited by CornedBee; 03-31-2009 at 11:28 AM. | ||
| CornedBee is offline | |
| | #13 |
| Registered User Join Date: Sep 2004 Location: California
Posts: 3,020
| Use virtual inheritance like so: Code: class B
{
public:
virtual void f() {}
};
class C : public virtual B
{
};
class D : public C, public virtual B
{
public:
virtual void f() {B::f();} // error: cannot call member function ‘virtual void B::f()’ without object
};
|
| bithub is offline | |
| | #14 | |
| Kernel hacker Join Date: Jul 2007 Location: Farncombe, Surrey, England
Posts: 15,686
| Quote:
-- Mats
__________________ Compilers can produce warnings - make the compiler programmers happy: Use them! Please don't PM me for help - and no, I don't do help over instant messengers. | |
| matsp is offline | |
| | #15 | |
| Registered User Join Date: Jul 2003
Posts: 32
| Quote:
Anyway. So the conclusion is, this is not standard behavior, that I am asking for? | |
| Helix is offline | |
![]() |
| Tags |
| error, inheritance, multiple, object |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Multiple inheritance: casting yields different address | dwks | C++ Programming | 16 | 06-08-2009 03:03 PM |
| Multiple inheritance in C# | DavidP | C# Programming | 1 | 06-27-2008 04:41 PM |
| Virtual function and multiple inheritance | George2 | C++ Programming | 68 | 02-13-2008 01:15 AM |
| Multiple Inheritance - Size of Classes? | Zeusbwr | C++ Programming | 10 | 11-26-2004 09:04 AM |
| Multiple virtual inheritance | kitten | C++ Programming | 3 | 08-10-2001 10:04 PM |