C Board  

Go Back   C Board > General Programming Boards > C++ Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 03-31-2009, 04:09 AM   #1
Registered User
 
Join Date: Jul 2003
Posts: 32
Multiple inheritance issue

Hello all,

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
};
I am using:
g++ (GCC) 4.2.4 (Ubuntu 4.2.4-1ubuntu3)


Thanks!!
Helix is offline   Reply With Quote
Old 03-31-2009, 04:35 AM   #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();
}
You haven't got an object of type A, so you can't call 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
};
Now, the compiler complains that B is not going to be accessible in D, due to ambiguity. And I agree with that. I've got no idea what you are trying to achieve - almost all cases of inheriting the same class more than once in a derived class is caused by "bad thinking".

--
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   Reply With Quote
Old 03-31-2009, 04:52 AM   #3
Registered User
 
Join Date: Jul 2003
Posts: 32
Quote:
Originally Posted by matsp View Post
It's the same as this:
However, even if you have an object, you are still not going to know which B::f() to call.
It's not the same, because i'm calling f() from a nonstatic function so I *have* and object.
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   Reply With Quote
Old 03-31-2009, 05:13 AM   #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   Reply With Quote
Old 03-31-2009, 05:46 AM   #5
Registered User
 
Join Date: Jul 2003
Posts: 32
Quote:
Originally Posted by matsp View Post
How about this:
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
};
thanks

Last edited by Helix; 03-31-2009 at 05:49 AM.
Helix is offline   Reply With Quote
Old 03-31-2009, 06:22 AM   #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   Reply With Quote
Old 03-31-2009, 06:50 AM   #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   Reply With Quote
Old 03-31-2009, 07:43 AM   #8
Registered User
 
Join Date: Jul 2003
Posts: 32
Quote:
Originally Posted by grumpy View Post
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.
Grumpy, i worked a little to produce this minimalistic example, so to keep things simple. one thing I know for sure, is that I don't want B to be a virtual base class.

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   Reply With Quote
Old 03-31-2009, 07:48 AM   #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   Reply With Quote
Old 03-31-2009, 08:11 AM   #10
Registered User
 
Join Date: Jul 2003
Posts: 32
Quote:
Originally Posted by matsp View Post
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

Well I didn't mean that g++ should conform to Visual Studio .
I was just saying....
Helix is offline   Reply With Quote
Old 03-31-2009, 08:20 AM   #11
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
Quote:
Originally Posted by Helix View Post
Well I didn't mean that g++ should conform to Visual Studio .
I was just saying....
I didn't say you said that. I was just pointing out that for good and bad, Visual Studio does things that other compilers MAY or MAY NOT be able to do. Sometimes that's a good thing, sometimes it's not.

--
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   Reply With Quote
Old 03-31-2009, 10:28 AM   #12
Cat without Hat
 
CornedBee's Avatar
 
Join Date: Apr 2003
Posts: 8,492
Quote:
Originally Posted by Helix
But how do I invoke D::B::f() ?
Quote:
Originally Posted by matsp
Now, the compiler complains that B is not going to be accessible in D, due to ambiguity.
The compiler is right ...


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   Reply With Quote
Old 03-31-2009, 10:51 AM   #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   Reply With Quote
Old 03-31-2009, 01:24 PM   #14
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
Quote:
Originally Posted by bithub View Post
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
};
But that assumes (which I think is where the key point is) that there should only be one B instance within D. If that's not the case, then this solution will not work.

--
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   Reply With Quote
Old 03-31-2009, 02:21 PM   #15
Registered User
 
Join Date: Jul 2003
Posts: 32
Quote:
Originally Posted by matsp View Post
But that assumes (which I think is where the key point is) that there should only be one B instance within D. If that's not the case, then this solution will not work.
I did say I wanted multiple sub-object copies in my design.

Anyway.
So the conclusion is, this is not standard behavior, that I am asking for?
Helix is offline   Reply With Quote
Reply

Tags
error, inheritance, multiple, object

Thread Tools
Display Modes

Forum Jump

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


All times are GMT -6. The time now is 09:44 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22