What is the colon for after the parameters in a function definition in c++?

Started by
17 comments, last by Zahlman 16 years, 2 months ago
Hey all, Im fairly new to c++ and Im slightly confused about the following function definition: IvVector3::IvVector3(const IvVector3& other) : x( other.x ), y( other.y ), z( other.z ) { } It's the colon part after the parameters and before the function body that is confusing me. Is this the same as: IvVector3::IvVector3(const IvVector3& other) { x = other.x; y = other.y; z = other.z } If so what is the difference doing it the first way? Thanks for your time :)
Advertisement
Quote:Original post by Mco
If so what is the difference doing it the first way?


The first version initializes the members with the provided value. The second version initializes the members with default values, and then assigns the provided value to them.

It's called an 'initializer list'. This thread touches on the topic a bit, and also includes a link to a C++ FAQ entry that should help clear things up for you.
There's a couple of reasons to use initializer lists instead of assigning in the constructor's body:

1) Clarity, it's clearer and more concise that you're perform initialisation and you don't have to worry about prefixing everything with 'this.' if your parameter names are the same as your member variable names (eg: IvVector3::IvVector3(float x, float y, float z) : x(x), y(y), z(z) { })

2) Performance, assigning in the constructor's body means that the member variables are first default constructed, then assigned (using IvVector3::IvVector3() and IvVector3::operator=(const &IvVector3& v) respectively). With builtin types this won't make any difference, but for custom types with non-trivial/expensive constructors this double initialisation can hurt you performance-wise.

There's also reason the not use the initialiser list:

1) You cannot initialise arrays in the initialiser list, the syntax just doesn't exist in C++.

2) If you want to pass 'this' to a member variable's constructor. While allowed you can run into problems if the member's constructor tries to use the 'this' pointer immediately as your object may not have finished initialising yet.

3) If you want to pass a member variable into another member variables's constructor. Member variable's aren't constructed in the order they appear in the initialiser list, but rather in the order they're declared in the class. So again, while this is allowed it's usually a good idea to avoid it.

For example:
class MyClass{    C c;    B b;    A a;public:    MyClass() : a(), b(this), c(b) { }    void Func() { a.Func(); }};

This might seem OK by looking at the constructor, but the order of initialisation is really c(b), b(this), a(). C's constructor will be getting passed an uninitialised 'b', and if B's constructor tries to call this->Func() it'll end up calling A::Func() with an uninitialised 'a'.
"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
Thanks for the quick replies :)

That's really cleared things up for me, especially the comprehensive reply from joanusdmentia.

That's also a very handy C++ FAQ!!!

Thanks!!
Also, to be pedantic, that is not a function, rather it is a "constructor" which is a special method used to initialize an instance of a class or struct.

You cannot apply the member list initializer syntax to other methods or functions, only to constructors.

throw table_exception("(? ???)? ? ???");

Quote:Original post by ravyne2001
Also, to be pedantic, that is not a function, rather it is a "constructor" which is a special method used to initialize an instance of a class or struct.


To be pedantic, C++ doesn't have "methods", it has member functions. Constructors are a type of member function, and are still functions.
/me tears hair out.

This is easily one of the most commonly asked questions about C++. Why does seemingly noone know about such a basic language feature, ten years later?
Quote:Original post by Zahlman
Why does seemingly noone know about such a basic language feature, ten years later?
Because they're "fairly new to c++ and slightly confused"?
Quote:Original post by Zahlman
/me tears hair out.

This is easily one of the most commonly asked questions about C++. Why does seemingly noone know about such a basic language feature, ten years later?


Because the recommended way to learn C++ is to learn C first. Or Java. Or better yet, any other language which has single-form constructors.

And to bring us back a point raised in another thread:
Why doesn't anybody teach RAII? Constructors are essentially implied there.

This topic is closed to new replies.

Advertisement