Skip to content

Commit 03dca83

Browse files
author
mikeblome
committed
merged with master and added new file
1 parent 7e625c3 commit 03dca83

1 file changed

Lines changed: 111 additions & 0 deletions

File tree

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
---
2+
title: "Delegating constructors (C++)"
3+
description: "Use delegating constructors in C++ to invoke other constructors and reduce code repetition."
4+
ms.date: "11/19/2019"
5+
---
6+
7+
# Delegating constructors
8+
9+
Many classes have multiple constructors that do similar things—for example, validate parameters:
10+
11+
```cpp
12+
class class_c {
13+
public:
14+
int max;
15+
int min;
16+
int middle;
17+
18+
class_c() {}
19+
class_c(int my_max) {
20+
max = my_max > 0 ? my_max : 10;
21+
}
22+
class_c(int my_max, int my_min) {
23+
max = my_max > 0 ? my_max : 10;
24+
min = my_min > 0 && my_min < max ? my_min : 1;
25+
}
26+
class_c(int my_max, int my_min, int my_middle) {
27+
max = my_max > 0 ? my_max : 10;
28+
min = my_min > 0 && my_min < max ? my_min : 1;
29+
middle = my_middle < max && my_middle > min ? my_middle : 5;
30+
}
31+
};
32+
```
33+
34+
You could reduce the repetitive code by adding a function that does all of the validation, but the code for `class_c` would be easier to understand and maintain if one constructor could delegate some of the work to another one. To add delegating constructors, use the `constructor (. . .) : constructor (. . .)` syntax:
35+
36+
```cpp
37+
class class_c {
38+
public:
39+
int max;
40+
int min;
41+
int middle;
42+
43+
class_c(int my_max) {
44+
max = my_max > 0 ? my_max : 10;
45+
}
46+
class_c(int my_max, int my_min) : class_c(my_max) {
47+
min = my_min > 0 && my_min < max ? my_min : 1;
48+
}
49+
class_c(int my_max, int my_min, int my_middle) : class_c (my_max, my_min){
50+
middle = my_middle < max && my_middle > min ? my_middle : 5;
51+
}
52+
};
53+
int main() {
54+
55+
class_c c1{ 1, 3, 2 };
56+
}
57+
```
58+
59+
As you step through the previous example, notice that the constructor `class_c(int, int, int)` first calls the constructor `class_c(int, int)`, which in turn calls `class_c(int)`. Each of the constructors performs only the work that is not performed by the other constructors.
60+
61+
The first constructor that's called initializes the object so that all of its members are initialized at that point. You can’t do member initialization in a constructor that delegates to another constructor, as shown here:
62+
63+
```cpp
64+
class class_a {
65+
public:
66+
class_a() {}
67+
// member initialization here, no delegate
68+
class_a(string str) : m_string{ str } {}
69+
70+
//can’t do member initialization here
71+
// error C3511: a call to a delegating constructor shall be the only member-initializer
72+
class_a(string str, double dbl) : class_a(str) , m_double{ dbl } {}
73+
74+
// only member assignment
75+
class_a(string str, double dbl) : class_a(str) { m_double = dbl; }
76+
double m_double{ 1.0 };
77+
string m_string;
78+
};
79+
```
80+
81+
The next example shows the use of non-static data-member initializers. Notice that if a constructor also initializes a given data member, the member initializer is overridden:
82+
83+
```cpp
84+
class class_a {
85+
public:
86+
class_a() {}
87+
class_a(string str) : m_string{ str } {}
88+
class_a(string str, double dbl) : class_a(str) { m_double = dbl; }
89+
double m_double{ 1.0 };
90+
string m_string{ m_double < 10.0 ? "alpha" : "beta" };
91+
};
92+
93+
int main() {
94+
class_a a{ "hello", 2.0 }; //expect a.m_double == 2.0, a.m_string == "hello"
95+
int y = 4;
96+
}
97+
```
98+
99+
The constructor delegation syntax doesn't prevent the accidental creation of constructor recursion—Constructor1 calls Constructor2 which calls Constructor1—and no errors are thrown until there is a stack overflow. It's your responsibility to avoid cycles.
100+
101+
```cpp
102+
class class_f{
103+
public:
104+
int max;
105+
int min;
106+
107+
// don't do this
108+
class_f() : class_f(6, 3){ }
109+
class_f(int my_max, int my_min) : class_f() { }
110+
};
111+
```

0 commit comments

Comments
 (0)