Jump to content
  • Advertisement
Sign in to follow this  
jamesd128

c++: passing class pointers into constructors

This topic is 2941 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm just having trouble understanding whats going on here. When I try to compile this code I get the following error error C2040: 'cfg' : 'Wrapper' differs in levels of indirection from 'Cfg *' Could someone please explain what's happening?
class Cfg{
	int stuff;
};

class Wrapper{
	public:
		Wrapper(Cfg *cfg){}
		Wrapper(){
			Cfg *cfg = new Cfg();
			Wrapper(cfg);
		}
};


Share this post


Link to post
Share on other sites
Advertisement
I'm guessing that you're trying to have one constructor call another one?

What's happening is that your code is (almost) creating a temporary Wrapper object inside the constructor.
class Wrapper{
public:
Wrapper(Cfg *cfg){ ... }
Wrapper(){
Cfg *cfg = new Cfg;
Wrapper newTemporaryWrapperObject(cfg);
}
};
In C++, if you want two (or more) constructors to share some code, you've got to do it yourself. e.g.
class Wrapper{
public:
Wrapper(Cfg *cfg){ Init(cfg); }
Wrapper(){ Init(new Cfg); }
private:
void Init(Cfg *cfg){ ... }
};
Or in this case you can merge them into one constructor using default arguments:
class Wrapper{
public:
Wrapper(Cfg *cfg=0)
{
if( !cfg )
cfg = new Cfg;
...
}
};

Share this post


Link to post
Share on other sites
Ah that fixes it, didn't realize you couldn't call other constructors like that in c++.

If you know though, why exactly does that "differs in levels of indirection" error come up?

Share this post


Link to post
Share on other sites
hmm, my guess is its trying to create a temporary object using the default copy sontructor, which expects (reference to) another Wrapper object as a parameter and not a *Cfg.

Could be wrong though, maybe someone can knows why exactly it is that you can't call constructors from constructors in C++?

Share this post


Link to post
Share on other sites
In GCC 4.4 I get the slightly more helpful error messages:

main.cpp: In constructor 'Wrapper::Wrapper()':
main.cpp:10: error: conflicting declaration 'Wrapper cfg'
main.cpp:9: error: 'cfg' has a previous declaration as 'Cfg* cfg'


So it seems like it ignores the parenthesis on "Wrapper(cfg);", and parses it as "Wrapper cfg;" instead. I'm actually a bit surprised at this, since this only seems to be the case if the constructor takes one argument that is a variable. But I guess no one is surprised that C++ isn't always consistent... I'm sure that there's some weird syntax one can use to call the constructor in the way you tried. Anyway, if you would call the constructor with for example "Wrapper(new Cfg());" instead, then it works, but doesn't really do what you want it to as it just creates a temporary instance of your class as Hodgman explained.

Share this post


Link to post
Share on other sites
Quote:
Original post by michaweyel
Could be wrong though, maybe someone can knows why exactly it is that you can't call constructors from constructors in C++?

You can't call constructors at all in C++. They are not functions.

You can construct an object in C++, which will invoke one of the class's constructors as a part of that process. You can not call the constructor directly.

Do not be confused the the syntax.

Share this post


Link to post
Share on other sites
Quote:
Original post by Perost
In GCC 4.4 I get the slightly more helpful error messages:
*** Source Snippet Removed ***
So it seems like it ignores the parenthesis on "Wrapper(cfg);", and parses it as "Wrapper cfg;" instead. I'm actually a bit surprised at this, since this only seems to be the case if the constructor takes one argument that is a variable. But I guess no one is surprised that C++ isn't always consistent... I'm sure that there's some weird syntax one can use to call the constructor in the way you tried. Anyway, if you would call the constructor with for example "Wrapper(new Cfg());" instead, then it works, but doesn't really do what you want it to as it just creates a temporary instance of your class as Hodgman explained.


I think it's actually interpreting that as a c-style cast. It's kind of fortunate too because otherwise there would have been no error at all and jamesd128 would have been left with the more confusing problem of why his default constructor wasn't doing anything.

Share this post


Link to post
Share on other sites
Quote:
Original post by wild_pointer
Quote:
Original post by Perost
In GCC 4.4 I get the slightly more helpful error messages:
*** Source Snippet Removed ***
So it seems like it ignores the parenthesis on "Wrapper(cfg);", and parses it as "Wrapper cfg;" instead. I'm actually a bit surprised at this, since this only seems to be the case if the constructor takes one argument that is a variable. But I guess no one is surprised that C++ isn't always consistent... I'm sure that there's some weird syntax one can use to call the constructor in the way you tried. Anyway, if you would call the constructor with for example "Wrapper(new Cfg());" instead, then it works, but doesn't really do what you want it to as it just creates a temporary instance of your class as Hodgman explained.


I think it's actually interpreting that as a c-style cast. It's kind of fortunate too because otherwise there would have been no error at all and jamesd128 would have been left with the more confusing problem of why his default constructor wasn't doing anything.

Actually, I think GCCs error message is quite clear that it interprets the line as a declaration.

Share this post


Link to post
Share on other sites
Quote:
Original post by Bregma
You can't call constructors at all in C++. They are not functions.

Actually they are functions and are one instance of the special member (drum roll) functions.
Quote:

You can construct an object in C++, which will invoke one of the class's constructors as a part of that process.
True
Quote:
You can not call the constructor directly.

You can create an unnamed temporary "Foo();" for example.
Quote:
Do not be confused the the syntax.

I won't :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!