C++ Constructors

Started by
24 comments, last by Mayrel 22 years, 4 months ago
quote:Original post by masonium

Actually, I dont think that constructors have to be public. I''ve seen many instances where there are private constructors. Why, I''m not sure.



Because you want to control where objects are created. You have a factory method which creates the objects, or a method to obtain a pointer to a singleton (not that much different). Or possibly you don''t want objects to be created on the stack.

If your constructor is private then only your method can create an object of that type. All object creation is bottle-necked and you can choose to create a new object, return an existing poitner or whatever. if your constructor is public you lose this control because a client can create objects in any part of the code.

--

MP3 Dancer

Get A Stripper on your desktop

Advertisement
quote:Original post by Anonymous Poster
Original post by DanG
Mayrel, what you''re doing is illegal.

Yeah. Im gonna report him to the FBI.


You''ll never take me alive, copper!

All your bases belong to us (I know. It''s irony.)
CoV
Aha. I got a copy of the standard. (Or, rather, the ''96 working paper, which is the nearest I can afford right now.)

quote:Original post by DanG
Mayrel, what you''re doing is illegal. After the parameter list in a constructor the ":" is fallowed by variables of the class and there initial values. THE EXCEPTION IS BASE CLASSES. You are free to put a call to your base class constructor in the intialization list. However this doesn''t seem to be what you are doing.

Correct, that isn''t what I''m doing. I had expected C++ to be consistent.
quote:
Calling a plain constructor is illigal.
This code will not compile.
Foo::Foo(int x, char * y)
{
Foo(x);
}
Run it in your compiler.

1) Calling a plain constructor is perfectly valid outside of a constructor. [5.2.3]

2) Calling a plain constructor inside a constructor for the same class is probably invalid because that''d result in an infinite loop. [Although I couldn''t see any rule against it in the standard.]

3) As it happens, C++ considers a plain Foo(x) to be a definition of a Foo named x, rather than an instantiation of Foo using x as the parameter. In the middle of an expression, it does the right thing.

All your bases belong to us (I know. It''s irony.)
CoV
quote:Original post by Mayrel
1) Calling a plain constructor is perfectly valid outside of a constructor. [5.2.3]

Yeah, but you make it sound like a constructor is just another function, which it''s not. You''re not just calling a function, you''re creating a temporary object too. ''Calling'' a constructor is just creating an object with syntax that looks like a function call.

quote:2) Calling a plain constructor inside a constructor for the same class is probably invalid because that''d result in an infinite loop. [Although I couldn''t see any rule against it in the standard.]

Yeah, but that''s not the problem in this case. You could be using something other than Foo and it would still not work. The problem here is that you''re simply getting the syntax wrong More specifically, trying to initialise something that isn''t initialisable.

quote:3) As it happens, C++ considers a plain Foo(x) to be a definition of a Foo named x, rather than an instantiation of Foo using x as the parameter. In the middle of an expression, it does the right thing.

No - it considers ''Foo(x)'' to mean ''initialise the member object or base class called Foo with the value of x, as if the member or base class called Foo had its constructor called with x as the parameter. Since the object in question (the instance of Foo being constructed) has no member or base class called Foo (it IS Foo, it doesn''t contain Foo in any form), then it doesn''t work.

Basically, you can''t ''call'' one constructor from another, because they''re not simple functions like that.

To (pretty much) do what you intended, you need to separate out the construction from initialisation functions. Write one function to initialise the int stuff, one for the char* stuff, and call the relevant initialisers in the relevant constructors. That saves you the code duplication. It won''t save you duplicate constructions (although that won''t be an issue with basic data types as used here).

And to the poster who asked what the point of private constructors was: it stops people declaring instances of that object. You can then control access to creating that object via a static member function. One use of this would be to only create a given number of such objects, and enforce that restriction.
yeah it might be confusing for someone who learned java first (well it wasn''t for me but I am soooo amazing at everything, and not the slightest bit arrogant either ). In java derived class constructors you are allowed to call base class constructors (but only in the very first line of the derived constructor), if you don''t call one it calls the 0 argument version for you, if there is one. If there isn''t then you have to explicitly call one of the other ones that you have written.
quote:Original post by Kylotan
Yeah, but you make it sound like a constructor is just another function, which it''s not. You''re not just calling a function, you''re creating a temporary object too. ''Calling'' a constructor is just creating an object with syntax that looks like a function call.


You appear to have have misunderstood what I''m refering to in my previous post: I''m talking about "Foo(x)" appearing in the method body of the constructor, rather than in the initialisation list, which I know is not valid (the fact that I noticed it wasn''t valid is what prompted me to post my question in the first place.)

In the method itself, you *can* call Foo(x).

quote:
> 2) Calling a plain constructor inside a constructor for the
> same class is probably invalid because that''d result in an
> infinite loop. [Although I couldn''t see any rule against it in
> the standard.]
Yeah, but that''s not the problem in this case. You could be using something other than Foo and it would still not work. The problem here is that you''re simply getting the syntax wrong More specifically, trying to initialise something that isn''t initialisable.


You probably can''t call Foo(x) in the method body because that''d cause an infinite loop.

quote:
> 3) As it happens, C++ considers a plain Foo(x) to be a
> definition of a Foo named x, rather than an instantiation of
> Foo using x as the parameter. In the middle of an expression,
> it does the right thing.
No - it considers ''Foo(x)'' to mean ''initialise the member object or base class called Foo with the value of x, as if the member or base class called Foo had its constructor called with x as the parameter. Since the object in question (the instance of Foo being constructed) has no member or base class called Foo (it IS Foo, it doesn''t contain Foo in any form), then it doesn''t work.


Again, in the method body, Foo(x) is a declaration of a Foo called x. In the initialisation list, it''s not valid.

quote:
And to the poster who asked what the point of private constructors was: it stops people declaring instances of that object. You can then control access to creating that object via a static member function. One use of this would be to only create a given number of such objects, and enforce that restriction.


A possible useful application of this would be a UniqueString class in which each instance of the class is guaranteed to be unique:

    UniqueString x = UniqueString::makeString("foo");  UniqueString y = UniqueString::makeString("bar");  UniqueString z = UniqueString::makeString("foo");  


After this, z and x point to the same object. Although this would make instantiations of the objects slower, it would allow one to compare two strings in constant time: by keeping all the strings in some form of sorted sequence (whether a list or binary tree) and giving each one a number according to its position within the sequence, you can overload the relational operators to compare the sequence number.

Abolish Software Patents! | freepatents | lpf
CoV
Mayrel: no you''re wrong for the reasons people above have stated. Also stop saying "in the method". Constructors are not methods; they are not functions; they are just special. That Foo(x) example is even more wrong, just wrong, wrong, wrong. Go buy Bjarne Stroustrup''s The C++ Programming Language. It is the best book there is on C++.

If I can just sneak a question into this thread.

Is it mandatory for all classes to have constructors/destructors ? I have one that doesn''t
have either of these. Bad practice ? I never included
constructors because of dynamic memory allocation for
objects in the class. The size of these objects can
change over the runtime of the program as they are deleted,
then re-allocated to a different size.

Does a constructor have to know all the sizes of the objects within ?

Guy
Adulthood is the vehicle for making you childhood dreams come true.
quote:Original post by GuyJohnston

If I can just sneak a question into this thread.

Is it mandatory for all classes to have constructors/destructors ?


Not at all, although you should be aware that if you don''t provide any ctors/dtor, the compiler writes a default (no aruguments) ctor and a default (element by element) copy ctor.

quote:
I have one that doesn''t
have either of these. Bad practice ? I never included
constructors because of dynamic memory allocation for
objects in the class. The size of these objects can
change over the runtime of the program as they are deleted,
then re-allocated to a different size.

Does a constructor have to know all the sizes of the objects within ?

Guy


I have no idea what you are doing here, but it sounds like all kinds of trouble. First of all, an object always has a fixed size. You can have a pointer to an array of a variable number of elements, but if your object has any pointers as memebers then you almost always need a ctor a copy ctor an assignment opperator and a destructor.


Thank You A.P.

I do have constructors/destructors for those particular pointers.

What I was doing, though do to a recent re-write probably not necessary anymore. Was loading a sprite surface, bitmask. I was allowing the sprite to be destroyed so I could re-load it as a different sprite when the orginal was no longer needed. I did have constructors/destructors for those particular pointers. I destroyed/re-constructed them when when I wanted to reload them.

Guy
Adulthood is the vehicle for making you childhood dreams come true.

This topic is closed to new replies.

Advertisement