Connecting Tech Pros Worldwide Forums | Help | Site Map

Virtual inheritance and multiple files

Klaas Vantournhout
Guest
 
Posts: n/a
#1: Nov 19 '06
Hi,

Recently I obtained a problem with virtual inheritance when implementing
it in multiple files. To present the problem I have included at the
bottom of this post the code of the 4 files. I show results with the
gnu compiler but i have the same results with the intel compiler.

file1.cpp compiles without a problem, the problem occurs when compiling
file2.cpp. It complains about not finding the constructor of the class
base.

[klaas@blackdwarf cpptest]$ g++ -c -Wall file2.cpp
file2.cpp: In constructor 'doublederived::doublederived(int)':
file2.cpp:3: error: no matching function for call to 'base::base()'
file1.hpp:3: note: candidates are: base::base(int)
file1.hpp:1: note: base::base(const base&)

When derived does not virtual inherit base, this does not give a
problem. Is there a reason why this is not working?

Regards
Klaas

// file1.hpp
class base {
public:
base(int);
};

class derived : public virtual base {
public:
derived(int);
};

// file1.cpp
#include <iostream>
#include "file1.hpp"
base::base(int a) { std::cout << a << std::endl;}
derived::derived(int a) : base(a) { }

// file2.hpp
#include "file1.hpp"
class doublederived : public derived {
public:
doublederived(int);
};

// file2.cpp
#include "file2.hpp"
doublederived::doublederived(int a) : derived(a) { }

BobR
Guest
 
Posts: n/a
#2: Nov 20 '06

re: Virtual inheritance and multiple files



Klaas Vantournhout wrote in message
<4560e845$0$1120$ba620e4c@news.skynet.be>...
Quote:
>Hi,
>
>Recently I obtained a problem with virtual inheritance when implementing
>it in multiple files. To present the problem I have included at the
>bottom of this post the code of the 4 files. I show results with the
>gnu compiler but i have the same results with the intel compiler.
>
>file1.cpp compiles without a problem, the problem occurs when compiling
>file2.cpp. It complains about not finding the constructor of the class
>base.
>
>[klaas@blackdwarf cpptest]$ g++ -c -Wall file2.cpp
>file2.cpp: In constructor 'doublederived::doublederived(int)':
>file2.cpp:3: error: no matching function for call to 'base::base()'
>file1.hpp:3: note: candidates are: base::base(int)
>file1.hpp:1: note: base::base(const base&)
>
>When derived does not virtual inherit base, this does not give a
>problem. Is there a reason why this is not working?
>
>Regards
>Klaas
>
>// file1.hpp
>class base {
public:
base(int);
>};
>
>class derived : public virtual base {
public:
derived(int);
>};
>
>// file1.cpp
>#include <iostream>
>#include "file1.hpp"
>base::base(int a) { std::cout << a << std::endl;}
>derived::derived(int a) : base(a) { }
>
>// file2.hpp
>#include "file1.hpp"
>class doublederived : public derived {
public:
doublederived(int);
>};
>
>// file2.cpp
>#include "file2.hpp"
>doublederived::doublederived(int a) : derived(a) { }
I'm not real sharp on this one. I looked at Eckel's and found this (in
diamond example):

class Left : virtual public Top { public: <snip>
Left(int m, int n) : Top(m) { y = n; }
};

class Right : virtual public Top { public: <snip>
Right(int m, int n) : Top(m) { z = n; }
};

class Bottom : public Left, public Right {
int w;
public:
Bottom(int i, int j, int k, int m)
: Top(i), Left(0, j), Right(0, k) { w = m; }
};

Note how, even though Bottom did not directly derive from Top, it was still
initialised in Bottom.

So, maybe try(?):

doublederived::doublederived(int a) : base(a), derived(a) { }

Makes since to me because your error is in looking for a base default
constructor, instead of using your defined constructor.

I'm just guessing at this, but, it shouldn't hurt to try it.
I tried it (in a single file) and it worked.

--
Bob R
POVrookie


Frank
Guest
 
Posts: n/a
#3: Nov 20 '06

re: Virtual inheritance and multiple files


I think BobR gave the correct solution. In this case, virtual
inheritance makes the constructor of "base" delay to the most derived
class "'doublederived" and suppresses the call of it from "derived".
Actually, in the constructor of " base", if you don't invoke the
constructor of "base", its default constructor will be the first
candidate.

"BobR д
"
Quote:
Klaas Vantournhout wrote in message
<4560e845$0$1120$ba620e4c@news.skynet.be>...
Quote:
Hi,

Recently I obtained a problem with virtual inheritance when implementing
it in multiple files. To present the problem I have included at the
bottom of this post the code of the 4 files. I show results with the
gnu compiler but i have the same results with the intel compiler.

file1.cpp compiles without a problem, the problem occurs when compiling
file2.cpp. It complains about not finding the constructor of the class
base.

[klaas@blackdwarf cpptest]$ g++ -c -Wall file2.cpp
file2.cpp: In constructor 'doublederived::doublederived(int)':
file2.cpp:3: error: no matching function for call to 'base::base()'
file1.hpp:3: note: candidates are: base::base(int)
file1.hpp:1: note: base::base(const base&)

When derived does not virtual inherit base, this does not give a
problem. Is there a reason why this is not working?

Regards
Klaas

// file1.hpp
class base {
public:
base(int);
};

class derived : public virtual base {
public:
derived(int);
};

// file1.cpp
#include <iostream>
#include "file1.hpp"
base::base(int a) { std::cout << a << std::endl;}
derived::derived(int a) : base(a) { }

// file2.hpp
#include "file1.hpp"
class doublederived : public derived {
public:
doublederived(int);
};

// file2.cpp
#include "file2.hpp"
doublederived::doublederived(int a) : derived(a) { }
>
I'm not real sharp on this one. I looked at Eckel's and found this (in
diamond example):
>
class Left : virtual public Top { public: <snip>
Left(int m, int n) : Top(m) { y = n; }
};
>
class Right : virtual public Top { public: <snip>
Right(int m, int n) : Top(m) { z = n; }
};
>
class Bottom : public Left, public Right {
int w;
public:
Bottom(int i, int j, int k, int m)
: Top(i), Left(0, j), Right(0, k) { w = m; }
};
>
Note how, even though Bottom did not directly derive from Top, it was still
initialised in Bottom.
>
So, maybe try(?):
>
doublederived::doublederived(int a) : base(a), derived(a) { }
>
Makes since to me because your error is in looking for a base default
constructor, instead of using your defined constructor.
>
I'm just guessing at this, but, it shouldn't hurt to try it.
I tried it (in a single file) and it worked.

--
Bob R
POVrookie
Klaas Vantournhout
Guest
 
Posts: n/a
#4: Nov 20 '06

re: Virtual inheritance and multiple files


Thanks Bob and Frank, indeed that was it. The most derived class must
explicitly invoke the virutal base class's constructor.

Great

thanks both

klaas


Frank wrote:
Quote:
I think BobR gave the correct solution. In this case, virtual
inheritance makes the constructor of "base" delay to the most derived
class "'doublederived" and suppresses the call of it from "derived".
Actually, in the constructor of " base", if you don't invoke the
constructor of "base", its default constructor will be the first
candidate.
>
"BobR 写道:
"
Quote:
>Klaas Vantournhout wrote in message
><4560e845$0$1120$ba620e4c@news.skynet.be>...
Quote:
>>Hi,
>>>
>>Recently I obtained a problem with virtual inheritance when implementing
>>it in multiple files. To present the problem I have included at the
>>bottom of this post the code of the 4 files. I show results with the
>>gnu compiler but i have the same results with the intel compiler.
>>>
>>file1.cpp compiles without a problem, the problem occurs when compiling
>>file2.cpp. It complains about not finding the constructor of the class
>>base.
>>>
>>[klaas@blackdwarf cpptest]$ g++ -c -Wall file2.cpp
>>file2.cpp: In constructor 'doublederived::doublederived(int)':
>>file2.cpp:3: error: no matching function for call to 'base::base()'
>>file1.hpp:3: note: candidates are: base::base(int)
>>file1.hpp:1: note: base::base(const base&)
>>>
>>When derived does not virtual inherit base, this does not give a
>>problem. Is there a reason why this is not working?
>>>
>>Regards
>>Klaas
>>>
>>// file1.hpp
>>class base {
>> public:
>> base(int);
>>};
>>>
>>class derived : public virtual base {
>> public:
>> derived(int);
>>};
>>>
>>// file1.cpp
>>#include <iostream>
>>#include "file1.hpp"
>>base::base(int a) { std::cout << a << std::endl;}
>>derived::derived(int a) : base(a) { }
>>>
>>// file2.hpp
>>#include "file1.hpp"
>>class doublederived : public derived {
>> public:
>> doublederived(int);
>>};
>>>
>>// file2.cpp
>>#include "file2.hpp"
>>doublederived::doublederived(int a) : derived(a) { }
>I'm not real sharp on this one. I looked at Eckel's and found this (in
>diamond example):
>>
>class Left : virtual public Top { public: <snip>
> Left(int m, int n) : Top(m) { y = n; }
>};
>>
>class Right : virtual public Top { public: <snip>
> Right(int m, int n) : Top(m) { z = n; }
>};
>>
>class Bottom : public Left, public Right {
> int w;
>public:
> Bottom(int i, int j, int k, int m)
> : Top(i), Left(0, j), Right(0, k) { w = m; }
>};
>>
>Note how, even though Bottom did not directly derive from Top, it was still
>initialised in Bottom.
>>
>So, maybe try(?):
>>
>doublederived::doublederived(int a) : base(a), derived(a) { }
>>
>Makes since to me because your error is in looking for a base default
>constructor, instead of using your defined constructor.
>>
>I'm just guessing at this, but, it shouldn't hurt to try it.
>I tried it (in a single file) and it worked.
>>
>--
>Bob R
>POVrookie
>
Closed Thread