Archived

This topic is now archived and is closed to further replies.

I don't WANT a default constructor.

This topic is 5585 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

Ive created a class called Color that Im going to use to represent the R, G and B values in OpenGL color functions. I also have a class called Ball, and Im going to have a lot of balls in my OpenGl program ( yea, im sort of a newbie! ). I want each ball to have a different color, so the Ball class has a member variable declared like so: private: Color color; My Ball constructor accepts a color object and saves it like so: Ball::Ball(Color c) { color = c; Also, my Color object has 2 different constructors, each of which accept parameters (so i DON''T have a default constructor). I keep getting compile errors saying that "there is no appropriate default constructor available" for the Color class. It points to the Ball constructor as the culprit. Does this mean i have to define a default constructor for the Color class? Because I dont want to! Anytime a color object is created, I want it to be a specific chosen color. It doesnt make sence to me that I should be forced to provide a default constructor. I shouldnt have to change the design of my program for a strange syntax quirk. I must be doing something wrong. Can someone tell me what? P.S. I Was going to post some code, but I have a lot of it, and im not sure exactly what code is causing problems, So Ill just wait and see if anyone can solve this without code first. Thanks a lot in advance! Its not my fault I''''m the biggest and the strongest; I don''''t even exercise.

Share this post


Link to post
Share on other sites
You must have a default constructor. No way around it. Have it do nothing, or, do it like you should and make it initialize all member variables in the class.

[edit]BTW, it is possible to have more than one constructor, through function overloading. Make your declaration look like this:

Ball();
Ball(Color c);

then in your code:

Ball::Ball()
{
memset (color, 0, sizeof(color));
}
Ball::Ball(Color c)
{
color = c;
}

[edited by - Neosmyle on August 29, 2002 8:04:43 PM]

Share this post


Link to post
Share on other sites
AFAIK, you don't need a default constructor, but you have to make sure that every instance of Ball has arguments for the constructor, or else your compiler will complain. For example, you can't have

Ball b; //The compiler should flag this error

Furthermore, if your Color objects don't have a default constructor, your Ball constructor should not be

Ball::Ball(Color c) {
color = c;
...

but rather

Ball::Ball(Color c) : color(c){...}

Which is, BTW, the preferred method even if Color had a default constructor.

Cédric

EDIT: Clarified stuff and fixed grammar.

[edited by - cedricl on August 29, 2002 8:35:13 PM]

Share this post


Link to post
Share on other sites
I''m very probably wrong here, but isn''t it quicker to do...


  
class Ball
{
public:

Ball(Colour col) : m_Colour(col) {}

private:

Colour m_Colour;
};


...since doing this means that it won''t make a temporary copy on the stack of the Colour object that you pass into the contructor? Or am I remembering things from a long time ago when compilers weren''t quite as optimising as they are nowadays?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
you don''t have to have a default constructor but if you don''t you have to initialize everything, for example you have a vertex class with a color as a member:

  
struct Vertex
{
Color tint;
Vertex();
};

//ok so now you have to implement the contructor,

you try this but it is wrong

Vectex::Vertex()
{
tint=Color(255,255,255);
}

//that''s because tint has to have a legal value before

//you get into the body of the constructor, so use this instead


Vertex::Vertex() : tint(255,255,255)
{
}

Share this post


Link to post
Share on other sites
quote:
Original post by Andre the Giant
I keep getting compile errors saying that "there is no appropriate default constructor available" for the Color class. It points to the Ball constructor as the culprit.

Does this mean i have to define a default constructor for the Color class? Because I dont want to! Anytime a color object is created, I want it to be a specific chosen color. It doesnt make sence to me that I should be forced to provide a default constructor. I shouldnt have to change the design of my program for a strange syntax quirk. I must be doing something wrong.

Can someone tell me what?



Just make the default constructor, damn it...


class Color
{
Color() {} // default ctor == do nothing
...
};

Share this post


Link to post
Share on other sites
There seem to be two issues here:

First issue: Can you have a class without a default constructor? The answer is yes, like this:


    
class Ball {
private:
Ball(); //declare, but don't define!

Color col;
public:
Ball(const Color& c) : col(c) { }
}:


Provided you do not define a default constructor for Ball, the class will not have a default constructor. The same can be done for the copy constructor if you don't want that (and assignment as well, I'm certain).

Second issue: The error you quote is there is no appropriate default constructor available for the Color class . Note that this is talking about constructors on the Color class, not the Ball class. So the compiler is telling you that your Color class has no default constructor, but you are attempting to use it anyway.

Look to see where you are instatiating the Color class and figure out whether you need to provide parameters upon its construction, or provide a default constructor for Color.


---- --- -- -
Blue programmer needs food badly. Blue programmer is about to die!


[edited by - mossmoss on August 29, 2002 9:21:18 PM]

Share this post


Link to post
Share on other sites
Try something like this Andre

Ball(Color c = Color(255,255,255)) : color(c) {}


...
You don''t have to make the default ctor private, nor use a declare but don''t define trick to not have one. (You use that to hide copy ctor''s.)

This class has no default ctor:

class Object
{
public:
Object(int i) {}
};

A default ctor is made for you automatically iff (that''s if and only if) you do not define any other ctor''s.

Share this post


Link to post
Share on other sites
Another way (not necessarily good, but maybe):
You could always use color as an external object that is referenced by the ball, instead of the ball containing the color. Then you construct the color, and pass a reference to the color as a parameter of the ball constructor.

ie

  
class Ball {
Ball(Color *color);
~Ball();

private:
Color *c; /
}

Ball::Ball(Color *color) {
c = color;
}

// If each ball has it''s own color

Ball::~Ball() {
delete c;
}

func() {
Ball *ball = new Ball(new color(0.7, 0.2, 0.5));
delete ball;
}


More complicated, but it does have some uses, especially if multiple balls can share the same color.

Share this post


Link to post
Share on other sites
While you don''t need one, it becomes necissary when you decide to make an array of colors. There''s no way around it in that case -- what I do in cases like this is I make a default inline constructor that doesn''t do anything and doesn''t even set the color to a default color. That way if you make an array of colors, you don''t have to wait through initialization of color, especially since you''ll most likely be changing the value anyways.

--------------------
Matthew Calabrese
Realtime 3D Orchestra:
Programmer, Composer,
and 3D Artist/Animator
"I can see the music..."

Share this post


Link to post
Share on other sites
Note that the array-new and all STL containers make use of the default constructor.



Don''t listen to me. I''ve had too much coffee.

Share this post


Link to post
Share on other sites
You should NULL all your member pointers in the constructor before using them, because SAFE_DELETING them wont work if they are pointing to crap.
Some times is good to have default values for some variables. I think you''ll use your constructor more often than never.

Share this post


Link to post
Share on other sites
quote:
Original post by Sneftel
Note that the array-new and all STL containers make use of the default constructor.


Really? I always thought that the reason why there wasn't a 0 argument push_back() was that they didn't want to rule out objects without a default constructor...

And Oluseyi, how does a default constructor encourage RAII? If there is a 'dummy' default constructor that doesn't actually initialize the object, it discourages RAII, doesn't it? If there is no obvious choice for the default values, I don't think it's wise to provide a default ctor.

Cédric

EDIT: Ok, I see your point Oluseyi, my comment about RAII is pretty stupid now that I think about it. But as far as I can see, the only place where you really need a default constructor is when there is a stupid function that uses pointers to return values, eg.:

int x;
SomeFunctionThatInitializesX(&x);

But it doesn't seem very OO to me.

[edited by - cedricl on August 29, 2002 12:15:31 AM]

Share this post


Link to post
Share on other sites
What it comes down to is this: polymorphic classes shouldn''t have public ctor''s. PoD''s should have empty do-nothing ctor''s. Pointers & resource handles should be always be initialized in all ctor''s. Object memory management should be performed through overload new operators, beit burst acquistion using placement new, or a generic memory pool.

Java''s New considered Harmful" Note that although it says Java in the title, the arguements against new also apply to C++''s new.

Share this post


Link to post
Share on other sites
Andre the Giant said it was the Color class that needed a default constructor:

What''s the Color class code like? Do you have constructors?

I thought if you passed something by value it was constructed using the copy constructor not the default constructor.

Share this post


Link to post
Share on other sites
quote:
Original post by Magmai Kai Holmlor
What it comes down to is this: polymorphic classes shouldn''t have public ctor''s.

This, I don''t understand. Could you explain it? Did you mean that abstract base classes should have a protected contructor?

Cédric

Share this post


Link to post
Share on other sites
quote:
Original post by cedricl
This, I don''t understand. Could you explain it? Did you mean that abstract base classes should have a protected contructor?

Presumably, he means that polymorphic classes should be created by a factory which has specially privileged access to the ctor. The same argument regarding encapsulation applies to object creation as to anything - how and where the object is created should be transparent to the user of the object. The way to ensure the user does not dictate how the object comes into being is to disable the ctor and make them go via the factory.

For every design heuristic, there is an equal and opposite reaction. In this case, the danger is of premature generalisation.

Share this post


Link to post
Share on other sites
quote:
Original post by Magmai Kai Holmlor
The use of new directly means you know what class you are creating, and that is against the grain of polymorphism.

True, and theres a very sound technical argument for doing this. However, it is worth sometimes thinking for a while about when and why you want polymorphism - sometimes its appropriate, sometimes not. Too much polymorphism tends toward amorphism, which means there are few focal points within a design. Polymorphism provides a nice symmetry, but that must be offset against a backdrop of asymmetry else chaos will ensue, and nobody will be able to make any sense of the amorphous mass.

Share this post


Link to post
Share on other sites
quote:
Original post by Andre the Giant
private:
Color color;

Also, my Color object has 2 different constructors, each of which accept parameters (so i DON''T have a default constructor).

I keep getting compile errors saying that "there is no appropriate default constructor available" for the Color class. It points to the Ball constructor as the culprit.



If you have two constructors for Color but no default constructor, then you will need to declare the color object with parameter(s). This is most likely the source of your error. Try this:

Color color(x,y,z);

replacing the letters with the actual parameters used to construct a Color object.

Ken Murphy

Share this post


Link to post
Share on other sites
Yeah, for all of my polymorphic classes I have a "ModularXXXX" (where X is the name of base class). The modular class just has a pointer to a dynamically allocated instance of one of the base class''s children. I have "FreshStart" and "Convert" templated functions for switching between different types. All of the derived classes just have protected constructors. It''s probably good practice to keep them that way, but I don''t think it really makes that much of a difference if you make public constructors.

--------------------
Matthew Calabrese
Realtime 3D Orchestra:
Programmer, Composer,
and 3D Artist/Animator
"I can see the music..."

Share this post


Link to post
Share on other sites