Skip to main content
gamedev.net
🔒 Locked

C++ Question...

Started by Xelius Oct 19, 2000 at 8:34 AM 10 replies 1.3k views
Original Post
Xelius
Xelius
Okay, lately I've noticed that a lot of people, when writing their C++, write classes that have something like this:
        
class MyClass
{
public:
   MyClass(int sx) : x(sx);

   protected:

   int x;
}
        
I'm not sure if that's the right syntax, but I have never seen that in my life! I'm guessing that it's a short hand way of assigning x to a value when the constructor is called. Is that it? Let me know, it's been bugging the hell out of me and I couldn't find it anywhere in my C++ books. (I mean, I only have two, but it should be there somewhere...) Thanks, Edited by - Xelius on 10/19/00 8:34:44 AM
-------------------"Pointer?" -Anonymous-=Xelius=-
verily
verily

It is legal syntax. the variable x is being initialized via the member initialization list. it is also the place to initialize const member variables.

Anyways, don''t lose any sleep over it!



Redleaf
Redleaf
I believe that syntax is called a sub-constructor... or something like that.

--Nazrix is cool.
DJ_House
DJ_House
The above constructor does the exact same thing as:

MyClass(int sx) //Constructor
{
x = sx
}

I''ve started using the
MyClass(int sx) : x(sx);
method for simple classes and the other way for complex objects that contain other classes or structs.

One other thing you may begin to notice is a lot more people are putting a "C" infront of their classes, ie. CMyClass.
MadKeithV
MadKeithV
quote:
Original post by DJ_House

The above constructor does the exact same thing as:

MyClass(int sx) //Constructor
{
x = sx
}



It certainly does NOT do the same thing as the constructor you've shown.

1. It's called an "Initialiser list", and if your CPP books don't have anything about it, they are pretty bad books.

2. They are used to initialise member variables, usually ones that have a basic data type, like int or float, but you can initialise member data objects in the same way, provided they have accessible constructors.

3. They can give you a serious performance boost in the case of complex objects, because an initialiser list can be executed BEFORE entry into the actual body of the constructor - and hence the objects do not need additional construction when you've gone into the function.

I think I'd best explain that with an example.

Consider the class with normal constructor.

        
class CBar
{
public:
CBar( int v1 = 0, int v2 = 0 )
{
m_v1 = v1;
m_v2 = v2;
}

void SetValues( int v1, int v2 )
{
m_v1 = v1;
m_v2 = v2;
}

protected:
int m_v1;
int m_v1;
};

class CFoo
{
public:
CFoo()
{
m_bar.SetValues( 123, 456 );
}

protected:
CBar m_bar;
}


Ripping apart the constructor for CFoo - you can see that when the constructor is entered, m_bar has to be constructed. Otherwise you have no object. So the constructor is called, and then the function to set the values. m_v1 and m_v2 are set twice, which is unnecessary overhead.

Now consider this constructor for CFoo:
CFoo() : m_bar( 123, 456 ) {};

No more value setting though the function! You've saved yourself two integer assignments. Not much, but for complex objects this can really add up.


People might not remember what you said, or what you did, but they will always remember how you made them feel.
~ (V)^|) |<é!t|-| ~

Edited by - MadKeithV on October 19, 2000 10:20:02 AM
It's only funny 'till someone gets hurt.And then it's just hilarious.Unless it's you.
Xelius
Xelius
Cool. I guess it make sense to have it, I just had never seen it anywhere before. I also lied. I only have 1 C++ book. The other one that I have is the Microsoft Reference for C++ for Visual Studio, so that doesn't really count. (As far as I remember, it's just how to use C++ in VS6) The other book I have is "Jamsa C/C++ Programmer's Bible", by Kris Jamsa and Lars Klander. It's a great book for looking up stuff, but I was unable to find an example that used the "sub-constructor" as Redleaf called it. (Probably has only one example under that name, and that's why I couldn't find it.) Anyways, thanks for the replies.

L8r!





Edited by - Xelius on October 19, 2000 1:01:26 PM
-------------------"Pointer?" -Anonymous-=Xelius=-
Jaxks
Jaxks
It makes your code more faster(? My book says).
But the most important feature is that it is only way to initialize references.

BTW The MSVC6 Doc is just like C++ book.
groucho
groucho
Another example:

1) MyClass::MyClass() : _data(value) {}

2) MyClass::MyClass() { _data = value; }

Both do the same thing (initialize _data), but constructer 2)
causes a temporary object to be created, which is passed to
_data's assignment operator and then destructed, which is
inefficient.

For more info, see the C++ FAQ on this topic at:
http://marshall-cline.home.att.net/cpp-faq-lite/ctors.html#[10.6]

Better yet, buy the C++ FAQ book - it's got much more info
than does the online version and is well worth the money.
Onerous Amazon URL to follow:

http://www.amazon.com/exec/obidos/ASIN/0201309831/o/qid=972403283/sr=8-1/ref=aps_sr_b_1_3/002-0435265-6620036


--groucho

"Outside of a dog, a book is a man's best friend. Inside of a dog, it's too dark to read."

Edited by - groucho on October 24, 2000 12:06:12 PM
--groucho"Outside of a dog, a book is a man's best friend. Inside of a dog, it's too dark to read."
Daniel Benmergui
Daniel Benmergui
Besides the performance issue about constructing and the assigning (which is more that a performance issue, because many common use classes don´t allow assignment and copy, like CSocket)
initializer lists (the subconstructor term does not exists) are the only way to assign values to member references AND constants

an example:

class MyClass
{
public:
MyClass(OtherClass& child):m_child(childref),m_iTimeOut(1000)
private:
COtherClass& m_childref;
const int m_iTimeOut;
};


Edited by - Daniel Benmergui on October 24, 2000 5:35:17 PM
TV
TV
It is also the only way to initialize base classes from a derived class:
(yay, more code)


class CBase
{
private:
int BASEVAR;
public:
CBase(int INIT) : BASE(INIT)
{ }
};

class CDerv : public CBase
{
private:
int DERVVAR;
public:
CDerv(int BINIT, DINIT) : CBase(BINIT), DERVVAR(DINIT)
{ }
};



- Travois
Zipster
Zipster
Basically, it allows you to call a class constructor from its "housing" clase''s creation.
Shannon Barber
Shannon Barber
Those initializers call a copy construtor, which *should* produce the same results as assignment, but that''s not necessarily the case...

    
class MyClass{
public:
//This is both an inline constructor and it uses an initializer

MyClass(int sx) : x(sx){} //should be {} not a ;

protected:
int x;
};

//you could also do this:

class Stuff
{
public:
Stuff(int sx);
protected:
int x;
};

//non-inline constructor with initializer

Stuff::Stuff(int sx) : x(sx)
{
}
The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.