c++: passing class pointers into constructors

Started by
16 comments, last by way2lazy2care 13 years, 11 months ago
Quote:Original post by Hodgman
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.*** Source Snippet Removed ***In C++, if you want two (or more) constructors to share some code, you've got to do it yourself. e.g.*** Source Snippet Removed ***Or in this case you can merge them into one constructor using default arguments:*** Source Snippet Removed ***


on your last source bit, can you not use Wrapper(Cfg *cfg = new Cfg());?

I'm not sure about the limitations of default arguments as I've only ever used them for primitive data types.
Advertisement
Quote:
on your last source bit, can you not use Wrapper(Cfg *cfg = new Cfg());?

I'm not sure about the limitations of default arguments as I've only ever used them for primitive data types.


you could, but that would making pasing a Cfg instance impossible, because it would be overwritten by the new operator. The code as originally written allows passing a Cfg object, or a null pointer. The constructor will use the object if passed, or create a default one if it receives the null pointer.
#include <iostream>int main(){    int(i);    i = 10;    std::cout << i << '\n';}


vs

#include <iostream>int main(){    int i;    (int (i));    i = 10;    std::cout << i << '\n';}


Quote:
I think it's actually interpreting that as a c-style cast.


AFAIK, in a C-style cast the parenthesis are around the typename
(int)x;


Parenthesis around the variable mean a constructor / conversion through pseudo-constructor (for built-in types in which case it is pretty much equivalent to a cast) or, in some contexts, a variable declaration. The latter tends to come up as "the most vexing parse", because it can also occur in function parameter declarations:

std::vector<x> vec(std::istream_iterator<x>(fin), std::istream_iterator<x>());//that's a function declaration!! same as:std::vector<x> vec(std::istream_iterator<x> fin, std::istream_iterator<x>);
Quote:
You can create an unnamed temporary "Foo();" for example.

However, this is not "calling the constructor directly," it is just constructing a temporary. The standard even calls this and functional notation casts out as 'looking like an explicit call' to the constructor, even though they are not. You cannot call the constructor directly, because it doesn't have a name (12.1.1).

N.B. that this topic is too advanced for this forum.
The means of invoking constructor on some pre-existing memory location is placement new.

#include <new>class Cfg{	int stuff;};class Wrapper{	public:		Wrapper(Cfg *cfg){}		Wrapper(){			Cfg *cfg = new Cfg();			new(this) Wrapper(cfg);		}};


Except don't ever do this because you were not meant to construct the same instance more than once. That would be OK, if there wasn't an instance already within that memory.
I wonder how valid this is in regards to invoking undefined behaviour?
class Wrapper{	public:		Wrapper(Cfg *cfg){/*...*/}		Wrapper(){			this->~Wrapper();			Cfg *cfg = new Cfg();			new(this) Wrapper(cfg);		}};
*evil grin*
It's undefined behavior if the original Wrapper object is const with static or automatic storage duration, if Wrapper is not the most derived type, or if Wrapper contains any non-static data members whose type is const or a reference type. See section 3.8 in the standard (n.b. this is an area where ISO/IEC 14882:1998 and 14882:2003 differ).
Quote:Original post by Burnt_Fyr
Quote:
on your last source bit, can you not use Wrapper(Cfg *cfg = new Cfg());?

I'm not sure about the limitations of default arguments as I've only ever used them for primitive data types.


you could, but that would making pasing a Cfg instance impossible, because it would be overwritten by the new operator. The code as originally written allows passing a Cfg object, or a null pointer. The constructor will use the object if passed, or create a default one if it receives the null pointer.


I thought default parameters were only set to their default if something wasn't passed in. Now I am confused.

This topic is closed to new replies.

Advertisement