class Foo
{
Foo (int x);
Foo (int x, char *y);
Foo (int x, double y);
Foo (int x, Wombat *y);
}
Foo::Foo (int x, char *y)
: Foo(x)
{
/* char* specifific stuff */
}
|
🔒 Locked
C++ Constructors
Advertisement
Original Post
Hullo, I''ve had a bit of a problem with my constructors. The following illustrates the issue:
My compiler (VC++) complains that ''Foo(int)'' isn''t a member of ''Foo'', which seems blatently wrong to me.
Is my compiler right? If it is, how am I supposed to call one constructor from another.
All your bases belong to us (I know. It''s irony.)
After the ":" with a constructor implementation,
you initialize VARIABLES with var(value), it''s
not allowed to do function calls *there*.
Just call your overloaded func in the body,
like this:
Foo::Foo(....)
{
Foo(x);
}
you initialize VARIABLES with var(value), it''s
not allowed to do function calls *there*.
Just call your overloaded func in the body,
like this:
Foo::Foo(....)
{
Foo(x);
}
Well,I''m not sure if c++ "knows" it,
but I think I did something like this, and
can''t remember that the program did something
I didn''t tell it to do, so I suppose it works.
Well, what are u gonna do?
Do you init some vars, or allocating some mem in
the constructor? Maybe you won''t need to call
that function, but,
however, I think it works.
Just try.
What I wanted to tell you, is only that the
syntax of the constructor implementation is
like I said above, and the "()" after the
name doesn''t have anything to do with a function,
although it may look like that.
It sets a classe''s variable to (value),
nothing more.
but I think I did something like this, and
can''t remember that the program did something
I didn''t tell it to do, so I suppose it works.
Well, what are u gonna do?
Do you init some vars, or allocating some mem in
the constructor? Maybe you won''t need to call
that function, but,
however, I think it works.
Just try.
What I wanted to tell you, is only that the
syntax of the constructor implementation is
like I said above, and the "()" after the
name doesn''t have anything to do with a function,
although it may look like that.
It sets a classe''s variable to (value),
nothing more.
I don''t think that anyone else pointed this out but you don''t have a public, private, or protected section of your class, thats ok, but constructors have to be public and class members are private by default.
Jason Mickela
ICQ : 873518
E-Mail: jmickela@sbcglobal.net
------------------------------
"Evil attacks from all sides
but the greatest evil attacks
from within." Me
------------------------------
Jason Mickela
ICQ : 873518
E-Mail: jmickela@sbcglobal.net
------------------------------
"Evil attacks from all sides
but the greatest evil attacks
from within." Me
------------------------------
quote:
Original post by griffenjam
you don''t have a public, private, or protected section of your class, thats ok, but constructors have to be public
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.
Mayrel, what your 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.
The AP had probably the best idea.
To get your desired result, have a funtion called Init(x) that will do everything with the x variable. So the function Foo(int x) simply calls Init(x) and the others, like Foo(int x, char * y) call Init(x) then do their own thing.
Calling a plain constructor is illigal.
This code will not compile.
Foo::Foo(int x, char * y)
{
Foo(x);
}
RUn it in your compiler.
One last thing, there are several good reasons for having private constructors. One is when you want only a handful of classes to be able to make one of your objects, but want all to see it. By declaring the constructors private and haveing classes that can build one as Friends, you can keep others from doing something you don''t want. (if it''s jsut one class that can build, its better just to make it a private declaration in the class).
Anyway thats my little piece.
The AP had probably the best idea.
To get your desired result, have a funtion called Init(x) that will do everything with the x variable. So the function Foo(int x) simply calls Init(x) and the others, like Foo(int x, char * y) call Init(x) then do their own thing.
Calling a plain constructor is illigal.
This code will not compile.
Foo::Foo(int x, char * y)
{
Foo(x);
}
RUn it in your compiler.
One last thing, there are several good reasons for having private constructors. One is when you want only a handful of classes to be able to make one of your objects, but want all to see it. By declaring the constructors private and haveing classes that can build one as Friends, you can keep others from doing something you don''t want. (if it''s jsut one class that can build, its better just to make it a private declaration in the class).
Anyway thats my little piece.
Another detail which is easy to miss... you need a ; after your closing } for the class.
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.
--
Aha. I got a copy of the standard. (Or, rather, the ''96 working paper, which is the nearest I can afford right now.)
Correct, that isn''t what I''m doing. I had expected C++ to be consistent.
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.)
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.)
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
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.
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 wrongMore 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:
|
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
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
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
You can create constructors and destructors for smart-pointers (classes with operator * and operator -> overridden to act like pointers. I use auto_ptr occasionally and CComPtr (part of the ATL) quite a lot.
A key difference between C++ and Java lies herein:
Thou Shalt Not Perform Initialization in Thou''s Constructor
because Construction Shalt Not Fail.
An objective in C++ is to prevent every error you possibly can prevent at compile time - don''t rely on run-time exceptions to catch mistakes (which you must be doing if you''re performing initialization in a constructor). It''s not the C++ way.
A key difference between C++ and Java lies herein:
Thou Shalt Not Perform Initialization in Thou''s Constructor
because Construction Shalt Not Fail.
An objective in C++ is to prevent every error you possibly can prevent at compile time - don''t rely on run-time exceptions to catch mistakes (which you must be doing if you''re performing initialization in a constructor). It''s not the C++ way.
quote:
Original post by Anonymous Poster
Mayrel: no you're wrong for the reasons people above have stated.
I _was_ wrong for the reasons people, including myself, above have stated.
quote:
Also stop saying "in the method". Constructors are not methods; they are not functions; they are just special.
According to the Standard, a constructor is a special member function . That is the precise term used. If you must insult my intelligence, at least check up on your's first.
quote:
That Foo(x) example is even more wrong, just wrong, wrong, wrong.
Which one? Do you mean the Foo(x) example in the initialiser? If yes, I've already said that I know it's wrong. If you mean the Foo(x) example in the method body , then there's nothing prohibiting that in the Standard.
quote:
Go buy Bjarne Stroustrup's The C++ Programming Language. It is the best book there is on C++.
Shall I get you one whilst I'm there?
Abolish Software Patents! | freepatents | lpf
Edited by - Mayrel on November 24, 2001 4:54:39 AM
class Foo
{
Foo (int x);
Foo (int x, char *y);
Foo (int x, double y);
Foo (int x, Wombat *y);
};
Foo::Foo (int x, char *y) : Foo(x)
{
/* char* specifific stuff */
}
or this:
Foo::Foo (int x, char *y)
{
:: Foo(x) ;
/* char* specifific stuff */
}
Try this one... now figure out what you did wrong...!
{
Foo (int x);
Foo (int x, char *y);
Foo (int x, double y);
Foo (int x, Wombat *y);
};
Foo::Foo (int x, char *y) : Foo(x)
{
/* char* specifific stuff */
}
or this:
Foo::Foo (int x, char *y)
{
:: Foo(x) ;
/* char* specifific stuff */
}
Try this one... now figure out what you did wrong...!
quote:
Original post by Holden
Try this one... now figure out what you did wrong...!
I already did, and you only need to post once.
We both know what''s wrong with the sample you posted, and so does anyone else who''s been following this thread. Nobody''ll learn anything if I just repeat what''s already been said.
Abolish Software Patents! | freepatents | lpf
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement