forked from portfoliocourses/cplusplus-example-code
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmember_initializer_lists.cpp
More file actions
143 lines (125 loc) · 4.54 KB
/
member_initializer_lists.cpp
File metadata and controls
143 lines (125 loc) · 4.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*******************************************************************************
*
* Program: Member Initializer List Examples
*
* Description: Examples of how, why, and when to use member initializer lists
* in C++.
*
* YouTube Lesson: https://www.youtube.com/watch?v=X1dGUSVnavQ
*
* Author: Kevin Browne @ https://portfoliocourses.com
*
*******************************************************************************/
#include <iostream>
using namespace std;
// A class with a default constructor AND parametrized constructor
class Major
{
public:
string name;
// we initialize member variable name to the value "Undeclared"
Major() : name("Undeclared")
{
// we can still put code in the instructor that will run after the members
// are initialized, to do other work a constructor may need to do
cout << "Major Constructor (Undeclared)" << endl;
}
// init member variable name to the value of the parameter name
Major(string name) : name(name)
{
cout << "Major Constructor (" << name << ")" << endl;
}
};
// A class with NO default constructor
class Minor
{
public:
string name;
// init member variable name to the value of the parameter name
Minor(string name) : name(name) {}
};
class Student
{
public:
string name;
int start_year;
int grad_year;
// We can initialize a const member variable like this, but it will take
// on the same vaue for every object instance
// const string id = "abc";
// If we wish to provide potentially different values for the const member
// variables of objects, we need to use member initializer lists as below!
const string id;
// If a class has a default constructor AND a parameterized constructor, then
// BOTH the default constructor AND the parameterized constructor will be
// called to create objects *if* in addition to the below declaration of
// the member variable major we also initialized it in the constructor
// body with something like:
//
// Major major("something");
//
// ONLY if we initialize the object in a member initializer list can we
// prevent this from happening and only create the object once. This is
// important for performance reasons, as otherwise we are calling two
// constructors when only one is needed!
Major major;
// We must use member initializer lists to initialize reference member
// variables like &minor1
Minor &minor1;
// If an object member variable only has a parametrized constructor, then
// we must also initialize the member variable using a member initializer
// list.
Minor minor2;
Student(string name, long int start_year, string major,
Minor &minor) :
// We can use { } in addition to ( ) in member initializer lists, the
// difference is that { } will detect type narrowing errors... e.g. if we
// uncomment the { } version of start_year's initialization and comment out
// the ( ) version of start_year's initialization we will get an error as
// int (start_year member variable's type) is a narrower type able to
// represent fewer numbers than long int (start_year parameter's type).
name{name},
// start_year{start_year},
start_year(start_year),
grad_year(start_year + 4),
id(name.append(to_string(start_year))),
major(Major(major)),
minor1(minor),
minor2(Minor("Physics"))
{
cout << "Student Object Constructed!" << endl;
}
};
// When a derived class has a base class with no default constructor, we need
// to use a member initializer list to use the base class constructor
class MatureStudent : Student
{
public:
int age;
// We use the member initializer list to use Student's constructor...
MatureStudent(int age, string name,
long int start_year, string major,
Minor &minor) :
Student(name, start_year, major, minor),
age(age) {}
};
int main()
{
// Test out making a student object, as the code is written now this long int
// value should not cause a compiler error (though the int value for the start
// and grad year's will be incorrect due to a type narrowing issue).
//
// Everything else should work as expected!
//
long int year = 999999999999;
Minor minor("Economics");
Student s1("John", year, "Computer Science", minor);
cout << "Name: " << s1.name << endl
<< "Start Year: " << s1.start_year << endl
<< "Grad Year: " << s1.grad_year << endl
<< "ID: " << s1.id << endl
<< "Major: " << s1.major.name << endl
<< "Minor1: " << s1.minor1.name << endl
<< "Minor2: " << s1.minor2.name << endl;
return 0;
}