



Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
Community
Ask the community for help and clear up your study doubts
Discover the best universities in your country according to Docsity users
Free resources
Download our free guides on studying techniques, anxiety management strategies, and thesis advice from Docsity tutors
The concept of initializer lists in C++ and their usage in initializing object's instance variables before the constructor runs. It covers the process of object creation in C++, the need for initializer lists, and situations where they are mandatory. The document also discusses the syntax and benefits of using initializer lists.
What you will learn
Typology: Summaries
1 / 6
This page cannot be seen from the preview
Don't miss anything!
Winter 2007- Handout # Feburary 20, 2008
_________________________________________________________________________________________________________ Introduction Normally, when you create a class, you'll initialize all of its instance variables inside the constructor. However, in some cases you'll need to initialize instance variables before the constructor begins running. Perhaps you'll have a const instance variable that you cannot assign a value, or maybe you have a class as an instance variable where you do not want to use the default constructor. For situations like these, C++ has a construct called the initializer list that you can use to fine-tune the way your data members are set up. This handout discusses initializer list syntax, situations where initializer lists are appropriate, and some of the subtleties of initializer lists. How C++ Constructs Objects To fully understand why initializer lists exist in the first place, you'll need to understand the way that C++ creates and initializes new objects. Let's suppose you have the following class: class SimpleClass { public: SimpleClass(); private: int myInt; string myString; vector
New Instance of SimpleClass
Space allocated for all objects int myInt ??????? (garbage) string myString (object) Text: ??????? (garbage) Length: ??????? (garbage) vector
As you can see, the values of the instance variables myInt, myString, and myVector are correctly set up before the SimpleClass constructor is called. This is considerably more efficient than the previous version and will run much faster. Note that while in this example we used initializer lists to initialize all of the object's instance variables, there is no requirement that you do so. However, in practice it's usually a good idea to set up all variables in an initializer list to make clear what values you want for each of your data members. When Initializer Lists are Mandatory As seen in this previous example, initializer lists can be quite useful in terms of efficiency. However, there are times where initializer lists are the only syntactically legal way to set up your instance variables. Suppose we'd like to make an object called Counter that supports two functions, increment and decrement, that adjust an internal counter. However, we'd like to add the restriction that the Counter can't drop below 0 or exceed a user-defined limit. Thus we'll use a parametrized constructor that accepts an int representing the maximum value for the Counter and stores it as an instance variable. Since the value of the upper limit will never change, we'll mark it const so that we can't accidentally modify it in our code. The class definition for Counter thus looks something like this: class Counter { public: Counter(int maxValue); void increment(); void decrement(); int getValue() const; private: int value; const int maximum; }; Then we'd like the constructor to look like this: Counter::Counter(int maxValue) { value = 0; maximum = maxValue; // ERROR! } Unfortunately, the above code isn't valid because in the second line we're assigning a value to a variable marked const. Even though we're in the constructor, we still cannot violate the sanctity of constness. To fix this, we'll initialize the value of maximum in the initializer list, so that maximum will be initialized to the value of maxValue, rather than assigned the value maxValue. This is a subtle distinction, so make sure to think about it before proceeding. The correct version of the constructor is thus Counter::Counter(int maxValue) : value(0), maximum(maxValue) { // Empty constructor }