This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is this weird colon-member syntax in the constructor?
C++ initialization
I have just received a header file in a C++ program, and I cannot figure out what this line of code does:
Card(Value faceValue=deuce, Suit suit = clubs):
suit(suit), faceValue(faceValue) {}
What does the : mean, and why does replacing it with a ; (as I thought I should) break the code?
Sorry for the generalness of this question, but could someone please explain the purpose of these two lines?
Thank you for your time.
This looks like a constructor for the Card class. The part after the : is an initializer list, initializing the values of member variables (or parent classes, but I don't think that's applicable in this case). The body of the constructor is empty because everything it needed to do was done in the initializer list.
The : and what follow is the initialization list. The reason you use it instead of assigning the member variables in the constructor's body is that if you do it inside the constructors body, the default constructor will be called first and then the copy constructor or assignment operator will be called afterwards. By using the initialization list you skip the first step.
Initialization lists. It's the preferred way to initialize class constructors in C++.
It is used because it allows the initialization of const members of the class without compilation error.
Related
I have just learned about classes in C++. I know that data members can be initialized by using the member initialization list syntax (MIL), but I think it is not very intuitive to use, and I think it is a very ugly way to assign data members.
Apparently class inheritance in C++ MUST be done through this MIL syntax. I do not understand the rationale behind this and googling did not give me answers. I am also unable to find any counter-example to this rule. Every example I saw online about inheritance requires the MIL.
So my question is: Is it possible to set up an inheritance without the MIL?
If the answer is yes, please explain how.
If the answer is no, please explain why not. (give the rationale behind mandating the MIL for inheritance)
No, that is not possible in general. If the base class has a default constructor, you can omit its initializer in the constructor of the derived class if that is appropriate. Typically though, you will want to invoke a specific constructor, and the member initializer list is the place to do that.
The reason for this is the design of the language: all "direct subobjects" of a class, meaning the base class objects and non-static data members it introduces, are actually initialized even before the body of its constructor is entered. Explicit member initializers must be given for subobjects that cannot be default-initialized, otherwise the program is ill-formed (must be rejected by compilers). For further reference, see for example cppreference on constructors and member initializer lists.
In practice this means that, while a constructor can perform additional work after initialization, constructors with empty bodies are fairly common in C++, but ones with empty member initializer lists are not.
This question already has answers here:
delete modifier vs declaring function as private
(4 answers)
Closed 3 years ago.
I have seen a lot of books recommend using =delete, is this just clear what it means? (making the program more readable) rather than saying that it is a bad thing to set the copy constructor to private?
Thinks your answers
class A {
A(const A&);
// some functions and variable
public:
// or you can A(const A&)=delete;
// do something
};
This is a relatively new functionality (added in the 2011 revision of C++) whose main motivation surely was readability and clarity of intent. However, the difference is more than just cosmetic.
Remember that with a constructor declared in the class, nothing prevents some other translation unit from actually providing the definition. It is quite usual to just list a class' member functions in a header file and implement them in a separate .cpp. If someone uses the copy constructor from inside the class, the compiler will complain that the definition is missing ("undefined reference to..."). If a naive programmer somehow reaches the conclusion that you forgot to implement it because you never needed it, they can go ahead and do so. Suddenly your class is copyable, even though only from within its own member functions (and friends). The =delete constructor prevents this, and the compiler errors are nicer (usually along the lines of "the object can't be copied because the copy constructor was declared as deleted" rather than "undefined reference to ..." or "A::A is private within this context").
This question already has answers here:
What is this weird colon-member (" : ") syntax in the constructor?
(14 answers)
Closed 4 years ago.
I am going through the "Getting started with the Windows API" portion of MSDN, and ran into an aspect of C++ I'm having trouble understanding.
I've been looking in "The C++ Programming Language" by Stroustrup, and can't find this particular thing.
Please check the link to the relevant page on MSDN.
The line that I don't understand is:
BaseWindow() : m_hwnd(NULL) { }
This line is in the latter code snippet describing an object oriented approach to the subject. m_hwnd is of the type HWND.
I really have no idea what is happening here. I'm pretty sure it's a constructor that doesn't do much of anything, but this specific syntax is foreign to me. I must admit my C++ knowledge is mostly just "C with some C++ stuff added". I'm currently diving deep into Stroustrup to remedy that.
The colon is just a syntax divider between the constructor declaration and the constructor initializer list.
It's a way to directly construct (or initialize) member variables.
It's similar (but not equal) to
BaseWindow()
{
m_hwnd = NULL;
}
Another way to look at it: Lets say you define a normal local variable, and want to initialize it to a specific value. There are a couple of ways to doing it.
Definition (with default initialization) and assignment:
HWND hwnd;
hwnd = 0;
Definition and copy initialization:
HWND hwnd = 0;
Definition and direct initialization:
HWND hwnd(0);
With a constructor initializer list, you use direct initialization in the constructor, and it happens before the constructor function body is executed.
Note that templates doesn't play any part of this. And neither does inheritance, even though it's possible to "call" a parent class constructor using a constructor initializer list.
Lastly an important note: Constructor initializer lists should not be confused with std::initializer_list.
BaseWindow() : m_hwnd(NULL) { }
That declares a default constructor for BaseWindow, which initializes the m_hwnd with a NULL value.
It does not, however, guarantee that m_hwnd will always be initialized to NULL. For instance, the default copy constructor will not do that. An explicit copy constructor is not likely to do it, either.
Look at this code snippet:
Size::Size(int iSetWidth, int iSetHeight)
:iWidth(iSetWidth),
iHeight(iSetHeight)
{
}
Supposedly, this means the same thing as:
Size::Size(int iSetWidth, int iSetHeight)
{
iWidth=iSetWidth;
iHeight=iSetHeight;
}
Why would you use the former or the latter? And what is the name of the former?
No, they don't mean exactly the same.
When a constructor is executed, before entering the code block (the code between the curly braces), it constructs all object data members. What you do in the initializers (the code after the colon and before the curly braces) is to specify which constructors to use for those members. If you don't specify a constructor for a specific data member, the default constructor will be used.
So, if you use the initialization list (first example), the right constructors will be used for each member and no additional code is necessary. If you don't, first the default constructor is used and then the code inside the curly braces is executed.
In summary:
In your first example, each member is initialised using the appropriate constructor, probably the copy constructor.
In your second example, each member is constructed using the default constructor, and then some additional code is executed to initialise it, probably the assignment operator.
EDIT: Sorry, forgot to answer your questions in the last line.
The name of the code between the colon and the curly braces is initialisation list.
If you know which is the right constructor for a variable or data member, by all means use it. This is the reason why most classes have different constructors instead of just a default constructor. So you are better off using the initialization list.
The initialisation list is almost never slower than the other technique, and can easily be faster. A well known rule when writing code is "don't optimize prematurely", but there is a not so well known counterpart: don't pessimize prematurely. If you have two options for writing a piece of code and one of them can be better than the other, but does not involve additional work or complexity, use it. In your example there is no difference, since you are using a built-in type (int). But if you were using classes, there would be a difference, so get used to the initialization list.
THe former is called initilazation lists.
You can get plentyof articles for that.
The particular reasons for using intializer lists are given here
http://www.learncpp.com/cpp-tutorial/101-constructor-initialization-lists/
You can refer Effective C++ to get full insight into intializer lists.
Hope it is clear.
BTW, Bjarne Stroustrup said in The C++ Programming Language that some efficiency may be gained with initialization list and he recommended us to use initialization list!
I am very very new to C/C++ and not sure what the method is called. But thats why I am here trying to find the answer. let me show you an example
MyClass::MyClass() : valueOne(1), valueTwo(2)
{
//code
}
Where valueOne and valueTwo are class properties that are assigned values outside of the body, what method is this called and why is it done this way. Why not do it this way
MyClass::MyClass()
{
valueOne = 1;
valueTwo = 2
//code
}
If anyone can help me out that will be great.
That is an initializer list. You can initialize your member variables using an initializer list after the constructor.
By default the constructor will automatically create the objects that are member variables by calling their default constructors. By using an initializer list you can specify to use other constructors. Sometimes if your member variable has no constructor with no argument you have to use an initializer list.
Initialisation lists (the former style) are usually preferred for efficiency and performance reasons. Personally I prefer them for code readability reasons too since it separates simple initialisation from any complex logic in the constructor itself.
This is called an initialization list. It's done mainly for performance (with larger objects) or consistency (with built-in types like int).
It is preferred to initialize members in the initializer list. In your case it doesn't matter, but it is not possible to initialize an int& the way you did in the second code fragment. It is the only place where you can pass arguments to your base class constructor as well.
Also note, that the this pointer is accessible in the initializer list if used to reference data fields or member functions in the BASE classes only.