Question about C ++ method method

I have code in Image.cpp:

Image::Image( int width, int height, int depth ) : m_sFileName(0) { ... } and in Image.h: class Image: public DrawAble, public RenderAble { ... private : std::string *m_sFileName; }; 

My question is: what happens to m_sFilename in the first line? I assume it is set to NULL, but what does that mean. Do the same:

 Image::Image( int width, int height, int depth ) { m_sFileName(0); ... } 
+4
source share
7 answers

The first uses what is called an initialization list .

When you enter the constructor body, all class members must be constructed (so that they can be used). Therefore, if you have this:

 class Foo { public: Foo() : str() // this is implicit { str = "String."; } private: std::string str; }; 

So str is created and then assigned. It would be better:

 class Foo { public: Foo() : str("String.") { } private: std::string str; }; 

So str obtained directly. This does not affect your case, because pointers do not have a constructor.

It is generally considered good practice to use an initialization list over running code in the constructor. The initialization list should be used to initialize, the constructor should be used to run the code.

Also, why use a pointer to a string? If you need a string, use a string; not a pointer to a string. Most likely you really want a string.


More about initialization lists:

Initializer lists have more uses than just initializing class members. They can be used to pass arguments to the base constructors:

 class Foo { public: Foo(int i) { /* ... */ } } class Bar : public Foo { public: Bar() : Foo(2) // pass 2 into Foo constructor. // There is no other way of doing this. { /* ... */ } }; 

Or permanent members:

 class Foo { public: Foo() : pi(3.1415f) { pi = 3.1415f; // will not work, pi is const. } private: const float pi; }; 

Or links:

 class Foo { public: Foo(int& i) : intRef(i) // intRef refers to the i passed into this constructor { intRef = i; // does *not* set intRef to refer to i! // rather, it sets i as the value of // the int intRef refers to. } private: int &intRef; }; 
+11
source

This is called an initializer. You must get used to using them. In this case, it does not matter. But in other cases, their use cannot mean double initialization of a non-pointer. First with default values, and then with your values. And finally, the case of a member without a constructor without parameters. In these cases, you have no choice but to use an initializer.

+2
source

It will be the same as doing

 Image::Image( int width, int height, int depth ) { m_sFileName = 0; // ... } 

Note that using a pointer to std::string usually not a good idea, since an empty string is no less good than a marker, and you do not need to worry about destruction if you make it a regular member.

0
source
 m_sFileName(0) 

in the constructor body will be interpreted as a function call with the name m_sFileName. You can replace it with

 m_sFileName = 0; 

However, the recommended initialization is in the constructor initialization list, as in the first example. Any data item that is not initialized in the constructor initialization list will be automatically initialized by the default constructor of its type.

0
source

He does the same thing:

 Image::Image( int width, int height, int depth ) { m_sFileName = 0; ... } 
0
source

The syntax you use is:

 Image::Image( int width, int height, int depth ) : m_sFileName(0) { ... } 

called an initialization list. It will assign the value 0 to your member variable.

Using m_sFileName = 0; in the designer case will be less efficient because the element will be initialized twice (once automatically, because it is not included in the initialization list and the second time with your explicit initialization).

0
source

These two options are almost the same - you're right that

 : m_sFileName(0) 

calls m_sFileName to initialize to 0 .

The reason C ++ has this special initialization syntax becomes important when you want to create a const Image . (This is probably not what you want to do in this case, but it may be something you can do for the "lightweight" types.) For const Image , this is a const pointer in the constructor, as well as in each " normal "member function, and therefore m_sFileName=0 not allowed.

To solve this problem, C ++ has initialization lists that perform initialization rather than assignment. By the way, if m_sFileName was an object, besides considering const , there would be an additional difference: the m_sFileName constructor is called in the initialization list, while the assignment will cause the assignment operator.

In addition to all these considerations, initialization lists - a good way to communicate intent - means that you are initializing, not assigning.

0
source

All Articles