in c++ classes are constructors mandatory?

Started by
16 comments, last by visitor 16 years, 8 months ago
Quote:Original post by speciesUnknown
g_vector::g_vector()
{
x=0;y=0;z=1;w=1;
};

I found that this was slower than not having a constructor.


Not having a constructor would force the compiler to create one for you. Of course that's faster than initializing x, y, z and w. Why wouldn't it be?
Advertisement
Quote:Original post by SymLinked
Quote:Original post by speciesUnknown
g_vector::g_vector()
{
x=0;y=0;z=1;w=1;
};

I found that this was slower than not having a constructor.


Not having a constructor would force the compiler to create one for you. Of course that's faster than initializing x, y, z and w. Why wouldn't it be?



The main question is this:
Should I always let the compiler create an empty constructor, or should i always call one of mine, or can I have a mixture of both. The answer is the conclusion i came to above. Please read the entire thread to understand.

[Edited by - speciesUnknown on August 4, 2007 9:38:12 AM]
Don't thank me, thank the moon's gravitation pull! Post in My Journal and help me to not procrastinate!
Quote:Original post by speciesUnknown
Should I always let the compiler create an empty constructor, or should i always call one of mine, or can I have a mixture of both. The answer is the conclusion i came to above. Please read the entire thread to understand.


I would suggest providing your own, to place the class in an initialized state. If you take a performance hit as a consequence of this, then it can only happen in a situation such as:
Vector v; // Create a default-valued vectorv = value(); // Assign a value


Because in this situation, initializing v is an additional cost with regard to not initializing it. However, this situation should not happen, and you should always prefer:
Vector v = value(); // Initialize from final value


Quote:Original post by ToohrVyk
You're trying to save speed in the wrong place. A typical optimization for vectors in C++ is to use expression templates. This is because, with or without inlining and/or constructors, expressions such as vector a = b + c + d; will involve creation of two temporary vectors (one per add) where none is needed. You could of course use vector a = b; (a += c) += d; but it's less readable.

With expression templates, b + c + d would not create a vector, but rather an object of type, say:
vect::wrap<vect::add<vect::add<vect::const,vect::const>,vect::const> >
This object could then be used to initialize a by effectively performing the steps a = b; (a += c) += d;. So, even though the code would still look like vector a = b + c + d;, it would act as vector a = b; (a += c) += d;.


How about writing
a = b;a += c;a += d;


Readable *and* simple.

Quote:Original post by janta
Quote:Original post by ToohrVyk
You're trying to save speed in the wrong place. A typical optimization for vectors in C++ is to use expression templates. This is because, with or without inlining and/or constructors, expressions such as vector a = b + c + d; will involve creation of two temporary vectors (one per add) where none is needed. You could of course use vector a = b; (a += c) += d; but it's less readable.

With expression templates, b + c + d would not create a vector, but rather an object of type, say:
vect::wrap<vect::add<vect::add<vect::const,vect::const>,vect::const> >
This object could then be used to initialize a by effectively performing the steps a = b; (a += c) += d;. So, even though the code would still look like vector a = b + c + d;, it would act as vector a = b; (a += c) += d;.


How about writing
a = b;a += c;a += d;


Readable *and* simple.


Doesn't solve the initial problem, it's still redundant compared to a = b + c + d
Best regards, Omid
Quote:Original post by Wavarian
If you don't want to have to specify a constructor for your classes, then use a struct.


Wrong. In C++ the ONLY difference between structs and classes is default access. They are they same. Just different syntax for the same semantics. I never use the class keyword because I hate having to write "public: " in every type I define.

Quote:Original post by Glak
Quote:Original post by Wavarian
If you don't want to have to specify a constructor for your classes, then use a struct.


Wrong. In C++ the ONLY difference between structs and classes is default access. They are they same. Just different syntax for the same semantics


That's correct but people tend to see struct and think of a type that provides direct access to it's member variables, for example I'd make a math Vector class a 'struct' as you typically allow direct access to the individual elements of the vector, whereas I'd use a 'class' for a Window type.

As for constructors, what I typically do is provide a 'no_init' type for allowing construct in an uninitialised state (for example, with a math Vector). This allows the default construct to do the right thing (that is construct a valid, initializsed object) and also makes it perfectly clear if the vector is being left uninitialized.

struct Vector{    // Supress initialization of the elements for the rare cases    // when the cost of default initialization is too much, it    // will be optimized into a no-op in release builds    struct no_init {};    explicit Vector(no_init) { }    // Default initialization    Vector()        : x(0.0f), y(0.0f), z(0.0f) { }};void func(){    // A default initialized vector (ie. a zero vector)    Vector v1;    // An uninitialized vector    Vector v2(Vector::no_init);}
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
How about testing with something like:
void test_vector(){g_vector test_subject(12.0f, 3.0f, 9.0f, 0.0f);test_vector=(test_vector+test_vector*96.3)/12 - test_vector; //test_vector???}


And providing a suitable constructor:
g_vector::g_vector(float a, float b, float c, float d):    x(a), y(b), z(c), w(d){}


(I've added the f-s to prevent potential cast (or promotion) from int to float that might have some overhead. Also in constructors initializer list might be more optimal.)

This topic is closed to new replies.

Advertisement