469,366 Members | 2,286 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,366 developers. It's quick & easy.

Virtual inheritance and multiple files

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) { }
Nov 19 '06 #1
3 2103

Klaas Vantournhout wrote in message
<45**********************@news.skynet.be>...
>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
Nov 20 '06 #2
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 д
"
Klaas Vantournhout wrote in message
<45**********************@news.skynet.be>...
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
Nov 20 '06 #3
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:
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 写道:
"
>Klaas Vantournhout wrote in message
<45**********************@news.skynet.be>...
>>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
Nov 20 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Kapil Khosla | last post: by
18 posts views Thread by nenad | last post: by
4 posts views Thread by JKop | last post: by
14 posts views Thread by Bruno van Dooren | last post: by
3 posts views Thread by kikazaru | last post: by
2 posts views Thread by Heinz Ketchup | last post: by
23 posts views Thread by Dave Rahardja | last post: by
reply views Thread by =?Utf-8?B?Zmplcm9uaW1v?= | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
reply views Thread by suresh191 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.