辅导ECS 34留学生程序、讲解c++编程、c/c++编程辅导
- 首页 >> Python编程 ECS 34: Programming Assignment #7
Fall 2020
Contents
1 Changelog 1
2 General Submission Details 1
3 Grading Breakdown 1
4 Submitting on Gradescope 2
4.1 Regarding Autograder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
5 Your Programming Tasks 2
5.1 Part #1: Copy to Multiple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
5.2 Part #2: Run Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
5.3 Part #3: Templated Linked List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1 Changelog
You should always refer to the latest version of this document.
• v.1: Initial version.
2 General Submission Details
Partnering on this assignment is prohibited. If you have not already, you should read the section on
academic misconduct in the syllabus.
This assignment is due the night of Tuesday, December 15. Gradescope will say 12:30 AM on Wednesday, December 16,
due to the “grace period” (as described in the syllabus). Be careful about relying on the grace period for extra time; this could
be risky.
You should use the -Wall, -Werror, and -std=c++11 flags when compiling. The autograder will use these flags when it
compiles your code.
3 Grading Breakdown
As stated in the syllabus, this assignment is worth 4% of the final grade. Below is the breakdown of each part.
• Part #1: 2% (20 points)
• Part #2: 2% (20 points)
• Part #3: 5% (50 points)
Note on extra credit: I will set the points cutoff at 40 points, which means that it is possible to earn extra credit on
this assignment. 1
∗This content is protected and may not be shared, uploaded, or distributed.
1
If, due to unique circumstances that we discussed over email, the worth of programming assignment #7 is scaled up to be worth more than
4% of your final grade, the extra credit will not scale, i.e. you cannot earn more extra credit than other students.
1
4 Submitting on Gradescope
You should only submit list.hpp, list.inl, and the two shell scripts. You have infinite submissions until the deadline.
During the 10/02 lecture, I talked about how to change the active submission, just in case that is something that you
find yourself wanting to do.
4.1 Regarding Autograder
Your output must match mine exactly.
There is a description about how to interpret some of the autograder error messages in the directions for the first two
programming assignments. I will not repeat that description here.
5 Your Programming Tasks
5.1 Part #1: Copy to Multiple
Filename: cp_mult.sh
Motivation: Recall that the cp command can be used to copy multiple files into a destination directory, but it cannot be
used to copy one file into multiple destinations. You will write a script that does that.
Write a shell script that takes as argument a regular file (i.e. never a directory) and a list of destinations. The script
should copy the file into each of the given destinations. If not enough arguments are provided, then a usage message should
be printed and the script should return 1 (with exit 1); otherwise, the script should return 0. Note that just like cp, cp_mult.sh
can be used to make multiple copies of a file in the same directory.
Below are some examples of how your script should behave.
21 Usage : ./ cp_mult . sh [ src ] [ dest1 ] ...
22 $ echo $?
23 1
24 $ ./ cp_mult . sh vals . txt
25 Usage : ./ cp_mult . sh [ src ] [ dest1 ] ...
26 $ ls *. txt
27 vals . txt
28 $ ./ cp_mult . sh vals . txt vals2 . txt vals3 . txt vals4 . txt
29 $ cat vals2 . txt
5.2 Part #2: Run Steps
Filename: run_steps.sh
Motivation: As a happy undergraduate student, I encountered several situations in which I had to run an executable
multiple times with different command-line arguments and collect the output of each of those runs. As you can hopefully
imagine, doing this manually (i.e. typing each line into the terminal) would have been annoying; you can save time on such
a task by writing a script like the one you will write for this part.
Write a script that takes five arguments:
• A command to run (which could be an executable compiled with gcc). Note that it must be the exact command needed
to run it, not just the executable’s name (which is why you see ./test in the example instead of test).
• A start integer A.
• An end integer B.
• A step integer S.
• An output file.
The script should perform a series of runs of the given command. The first run should have A be passed as argument to
the command to run. In the next run, A + S should be passed. After that, A + 2S, then A + 3S, then A + 4S, and so on,
until the value passed would exceed B. Each run’s results should be logged into the output file. You may not assume this
output file exists, and its old contents should be overwritten.
The script assumes that the executable only takes an integer as its only command-line argument. If not enough arguments
are provided, then a usage message should be printed and the script should return 1 (with exit 1); otherwise, the script should
return 0.
Below are some examples of how your script should behave.
1 $ cat test .c
2 # include < stdio .h >
3
4 int main ( int argc , char * argv [])
5 {
6 printf (" Provided : %s \n", argv [1]) ;
7 }
8 $ gcc - Wall - Werror test . c -o test
9 $ ./ run_steps . sh ./ test 10 100 5 output1 . txt
10 $ cat output1 . txt
11 === 10 ===
12 Provided : 10
13 === 15 ===
14 Provided : 15
15 === 20 ===
16 Provided : 20
17 === 25 ===
18 Provided : 25
19 === 30 ===
20 Provided : 30
21 === 35 ===
22 Provided : 35
23 === 40 ===
24 Provided : 40
25 === 45 ===
26 Provided : 45
27 === 50 ===
28 Provided : 50
29 === 55 ===
30 Provided : 55
31 === 60 ===
32 Provided : 60
33 === 65 ===
34 Provided : 65
35 === 70 ===
36 Provided : 70
37 === 75 ===
38 Provided : 75
39 === 80 ===
40 Provided : 80
41 === 85 ===
3
42 Provided : 85
43 === 90 ===
44 Provided : 90
45 === 95 ===
46 Provided : 95
47 === 100 ===
48 Provided : 100
49 $ ./ run_steps . sh ./ test 50 80 10 output2 . txt
50 $ cat output2 . txt
51 === 50 ===
52 Provided : 50
53 === 60 ===
54 Provided : 60
55 === 70 ===
56 Provided : 70
57 === 80 ===
58 Provided : 80
59 $ cat test2 .c
60 # include < stdio .h >
61 # include < stdlib .h >
62
63 int main ( int argc , char * argv [])
64 {
65 int num = atoi ( argv [1]) ;
66 if ( num < 100)
67 printf (" Less than 100.\ n ") ;
68 else
69 printf (" Greater than or equal to 100.\ n ") ;
70 }
71 $ gcc - Wall - Werror test2 .c -o test2
72 $ ./ run_steps . sh ./ test2 97 104 2 output3 . txt
73 $ echo $?
74 0
75 $ cat output3 . txt
76 === 97 ===
77 Less than 100.
78 === 99 ===
79 Less than 100.
80 === 101 ===
81 Greater than or equal to 100.
82 === 103 ===
83 Greater than or equal to 100.
84 $ ./ run_steps . sh ./ test2 97 104
85 Usage : ./ run_steps . sh [ executable ] [ start ] [ end ] [ step ] [ outfile ]
86 $ echo $?
87 1
88 $
5.3 Part #3: Templated Linked List
Filenames: list.hpp and list.inl
Look at the files list.hpp and list.inl that are provided on Canvas. These files contain the incomplete definition of a
templated linked list. You are to implement this class’ methods. In the header file, I describe what each method is supposed
to.
You are not allowed to use smart pointers in this assignment. (We will talk about these in slide deck #13.)
Manual review: I will do a quick manual review of your submission after the deadline in order to check that you obey
the time complexity constraints (where applicable), that you do not use smart pointers, and that you do not have public
member variables in class List.
Suggestions/tips:
• Recommended order of completion: I would probably start with the constructor, pushFront(), pushBack(), and
operator<<. I would consider the copy constructor, copy assignment operator, and destructor to be the hardest parts.
• Required concepts: If you understand operator overloading, templates, and copy semantics well, then I would think
that this assignment should be comparable to programming assignment #5 (class UnweightedGraph) in difficulty, so make
sure to start by understanding the recent concepts.
• list.hpp vs. list.inl: Because list.inl is included in list.hpp, it isn’t important which functions you choose to define in
list.hpp vs. list.inl. I would recommend avoiding defining all of the required methods in one or the other; I think you
should get used to the syntax for both defining a method within the class (in list.hpp) and defining a method outside
4
the class (in list.inl). For operator<<, it did not seem that I could define it outside of class List, as the compiler seems
to put additional restrictions on a friend of a templated class; I could not find a workaround, but maybe there is one.
• Avoid duplicating code where possible: Certain methods and/or operators are so similar (e.g. pushBack() and
operator+=) that, probably, you should have one of them call the other.
• Template compiler error messages: If you ask any C++ programmer what the worst part of the language is, they
will likely say it’s the compiler error messages that you get when dealing with templates. The slightest mistake in dealing
with templates can generate a huge number of error messages, and this can occur even when you’re not explicitly using
templates (e.g. when you’re using std::string, which is a typedef for the templated class std::basic_string). As is
usually the case, you want to start looking at the first error message (in case that one causes all of the other ones), but
this requires some scrolling. An alternative that I’ve sometimes found helpful is to do the command g++ ... 2>&1 | head,
where 2>&1 redirects the standard error (the compiler error messages) of the g++ command to standard output so that
it can be pipelined into head.
• Initializer list error messages: If a compiler error is generated by one of your constructor initializer lists, the
compiler (at least, g++) will flag the last line that the initializer list reaches. This only matters if you spread the
initializer list across multiple lines like I tend to, but it’s something to be aware of, because it can be deceiving if the
cause of the error has to do with something towards the beginning of the initializer list instead of the end.
Below are examples of how your code should behave. You can find main.cpp on Canvas.
1 $ cat main . cpp
2 # include " list . hpp "
3
4 struct X
5 {
6 X () { std :: cout << " Constructor !\ n "; }
7 ~X () { std :: cout << " Destructor !\ n "; }
8 };
9
10 int main ()
11 {
12 std :: cout << std :: boolalpha ;
13 List < int > lst ;
14 lst . pushBack (15) ;
15 lst . pushFront (33) ;
16 lst . pushFront (20) ;
17 lst . pushBack (50) ;
18 lst . pushFront (40) ;
19 lst += 80;
20 std :: cout << lst ;
21 std :: cout << lst . length () << ’\n ’;
22 std :: cout << " lst [3]=" << lst [3] << ’\n ’;
23 lst [2] = 90;
24 std :: cout << lst ;
25 std :: cout << " Contains 50: " << lst . contains (50) << ’\n ’
26 << " Contains -10: " << lst . contains ( -10) << ’\n ’;
27 std :: cout << " Remove 50: " << lst . remove (50) << ’ ’ << lst ;
28 std :: cout << " Remove 80: " << lst . remove (80) << ’ ’ << lst ;
29 std :: cout << " Remove -10: " << lst . remove ( -10) << ’ ’ << lst ;
30 lst . pushFront (200) ;
31 lst . pushBack (300) ;
32 lst += 100;
33 std :: cout << lst ;
34 lst . remove (200) ;
35 lst -= 40;
36 std :: cout << lst ;
37 std :: cout << " Copy construction ...\ n ";
38 List < int > lst2 { lst };
39 lst2 . remove (90) ;
40 std :: cout << lst << lst2 ;
41 std :: cout << " Copy assignment ...\ n ";
42 lst2 = lst ;
43 std :: cout << lst << lst2 ;
44 lst . pushBack ( -400) ;
45 lst2 . pushFront ( -100) ;
46 lst2 += -200;
47 std :: cout << lst << lst2 ;
48 std :: cout << lst . length () << ’ ’ << lst2 . length () << ’\n ’;
49
50 std :: cout << " Trying strings ...\ n ";
51 List < std :: string > strings ;
5
52 std :: cout << strings ;
53 std :: cout << strings . length () << ’\n ’;
54 strings . pushBack (" def ") ;
55 strings . pushFront (" abc ") ;
56 strings += " ghi ";
57 std :: cout << strings ;
58 std :: cout << strings . length () << ’\n ’;
59 strings -= " gh ";
60 strings -= " abc ";
61 std :: cout << " After removing \" abc \": " << strings ;
62 std :: cout << strings . length () << ’\n ’;
63 strings . pushFront (" jklmn ") ;
64 std :: cout << strings ;
65 std :: cout << strings [2] << ’\n ’;
66 std :: cout << " Copy construction ...\ n ";
67 auto strings2 = strings ;
68 std :: cout << strings [1] << ’ ’ << strings2 [1] << ’\n ’;
69 strings . remove (" def ") ;
70 strings2 . pushFront (" op ") ;
71 std :: cout << " strings : " << strings
72 << " strings2 : " << strings2 ;
73 std :: cout << " strings [1]: " << strings [1] << ’\n ’
74 << " strings2 [1]: " << strings2 [1] << ’\n ’;
75
76 std :: cout << " Trying class X ...\ n ";
77 List objs ;
78 objs . pushBack (X {}) ;
79 std :: cout << " Trying out -of - range index ...\ n ";
80 try
81 {
82 auto o = objs [3];
83 }
84 catch ( const std :: out_of_range & ex )
85 {
86 std :: cerr << "I accept your exception !\ n ";
87 }
88 catch (...)
89 {
90 std :: cerr << " Wrong type of exception !\ n ";
91 }
92
93 std :: cout << std :: noboolalpha ;
94 }
95 $ g ++ - Wall - Werror main . cpp
96 $ ./ a. out
97 40 20 33 15 50 80
98 6
99 lst [3]=15
100 40 20 90 15 50 80
101 Contains 50: true
102 Contains -10: false
103 Remove 50: true 40 20 90 15 80
104 Remove 80: true 40 20 90 15
105 Remove -10: false 40 20 90 15
106 200 40 20 90 15 300 100
107 20 90 15 300 100
108 Copy construction ...
109 20 90 15 300 100
110 20 15 300 100
111 Copy assignment ...
112 20 90 15 300 100
113 20 90 15 300 100
114 20 90 15 300 100 -400
115 -100 20 90 15 300 100 -200
116 6 7
117 Trying strings ...
118
119 0
120 abc def ghi
121 3
122 After removing " abc ": def ghi
123 2
124 jklmn def ghi
125 ghi
6
126 Copy construction ...
127 def def
128 strings : jklmn ghi
129 strings2 : op jklmn def ghi
130 strings [1]: ghi
131 strings2 [1]: jklmn
132 Trying class X ...
133 Constructor !
134 Destructor !
135 Trying out - of - range index ...
136 I accept your exception !
137 Destructor !
138 $ valgrind ./ a . out > / dev / null
139 ...
140 ==3198== All heap blocks were freed -- no leaks are possible
141 ==3198==
142 ==3198== For counts of detected and suppressed errors , rerun with : -v
143 ==3198== ERROR SUMMARY : 0 errors from 0 contexts ( suppressed : 0 from 0)
144 $
7
Fall 2020
Contents
1 Changelog 1
2 General Submission Details 1
3 Grading Breakdown 1
4 Submitting on Gradescope 2
4.1 Regarding Autograder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
5 Your Programming Tasks 2
5.1 Part #1: Copy to Multiple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
5.2 Part #2: Run Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
5.3 Part #3: Templated Linked List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1 Changelog
You should always refer to the latest version of this document.
• v.1: Initial version.
2 General Submission Details
Partnering on this assignment is prohibited. If you have not already, you should read the section on
academic misconduct in the syllabus.
This assignment is due the night of Tuesday, December 15. Gradescope will say 12:30 AM on Wednesday, December 16,
due to the “grace period” (as described in the syllabus). Be careful about relying on the grace period for extra time; this could
be risky.
You should use the -Wall, -Werror, and -std=c++11 flags when compiling. The autograder will use these flags when it
compiles your code.
3 Grading Breakdown
As stated in the syllabus, this assignment is worth 4% of the final grade. Below is the breakdown of each part.
• Part #1: 2% (20 points)
• Part #2: 2% (20 points)
• Part #3: 5% (50 points)
Note on extra credit: I will set the points cutoff at 40 points, which means that it is possible to earn extra credit on
this assignment. 1
∗This content is protected and may not be shared, uploaded, or distributed.
1
If, due to unique circumstances that we discussed over email, the worth of programming assignment #7 is scaled up to be worth more than
4% of your final grade, the extra credit will not scale, i.e. you cannot earn more extra credit than other students.
1
4 Submitting on Gradescope
You should only submit list.hpp, list.inl, and the two shell scripts. You have infinite submissions until the deadline.
During the 10/02 lecture, I talked about how to change the active submission, just in case that is something that you
find yourself wanting to do.
4.1 Regarding Autograder
Your output must match mine exactly.
There is a description about how to interpret some of the autograder error messages in the directions for the first two
programming assignments. I will not repeat that description here.
5 Your Programming Tasks
5.1 Part #1: Copy to Multiple
Filename: cp_mult.sh
Motivation: Recall that the cp command can be used to copy multiple files into a destination directory, but it cannot be
used to copy one file into multiple destinations. You will write a script that does that.
Write a shell script that takes as argument a regular file (i.e. never a directory) and a list of destinations. The script
should copy the file into each of the given destinations. If not enough arguments are provided, then a usage message should
be printed and the script should return 1 (with exit 1); otherwise, the script should return 0. Note that just like cp, cp_mult.sh
can be used to make multiple copies of a file in the same directory.
Below are some examples of how your script should behave.
21 Usage : ./ cp_mult . sh [ src ] [ dest1 ] ...
22 $ echo $?
23 1
24 $ ./ cp_mult . sh vals . txt
25 Usage : ./ cp_mult . sh [ src ] [ dest1 ] ...
26 $ ls *. txt
27 vals . txt
28 $ ./ cp_mult . sh vals . txt vals2 . txt vals3 . txt vals4 . txt
29 $ cat vals2 . txt
5.2 Part #2: Run Steps
Filename: run_steps.sh
Motivation: As a happy undergraduate student, I encountered several situations in which I had to run an executable
multiple times with different command-line arguments and collect the output of each of those runs. As you can hopefully
imagine, doing this manually (i.e. typing each line into the terminal) would have been annoying; you can save time on such
a task by writing a script like the one you will write for this part.
Write a script that takes five arguments:
• A command to run (which could be an executable compiled with gcc). Note that it must be the exact command needed
to run it, not just the executable’s name (which is why you see ./test in the example instead of test).
• A start integer A.
• An end integer B.
• A step integer S.
• An output file.
The script should perform a series of runs of the given command. The first run should have A be passed as argument to
the command to run. In the next run, A + S should be passed. After that, A + 2S, then A + 3S, then A + 4S, and so on,
until the value passed would exceed B. Each run’s results should be logged into the output file. You may not assume this
output file exists, and its old contents should be overwritten.
The script assumes that the executable only takes an integer as its only command-line argument. If not enough arguments
are provided, then a usage message should be printed and the script should return 1 (with exit 1); otherwise, the script should
return 0.
Below are some examples of how your script should behave.
1 $ cat test .c
2 # include < stdio .h >
3
4 int main ( int argc , char * argv [])
5 {
6 printf (" Provided : %s \n", argv [1]) ;
7 }
8 $ gcc - Wall - Werror test . c -o test
9 $ ./ run_steps . sh ./ test 10 100 5 output1 . txt
10 $ cat output1 . txt
11 === 10 ===
12 Provided : 10
13 === 15 ===
14 Provided : 15
15 === 20 ===
16 Provided : 20
17 === 25 ===
18 Provided : 25
19 === 30 ===
20 Provided : 30
21 === 35 ===
22 Provided : 35
23 === 40 ===
24 Provided : 40
25 === 45 ===
26 Provided : 45
27 === 50 ===
28 Provided : 50
29 === 55 ===
30 Provided : 55
31 === 60 ===
32 Provided : 60
33 === 65 ===
34 Provided : 65
35 === 70 ===
36 Provided : 70
37 === 75 ===
38 Provided : 75
39 === 80 ===
40 Provided : 80
41 === 85 ===
3
42 Provided : 85
43 === 90 ===
44 Provided : 90
45 === 95 ===
46 Provided : 95
47 === 100 ===
48 Provided : 100
49 $ ./ run_steps . sh ./ test 50 80 10 output2 . txt
50 $ cat output2 . txt
51 === 50 ===
52 Provided : 50
53 === 60 ===
54 Provided : 60
55 === 70 ===
56 Provided : 70
57 === 80 ===
58 Provided : 80
59 $ cat test2 .c
60 # include < stdio .h >
61 # include < stdlib .h >
62
63 int main ( int argc , char * argv [])
64 {
65 int num = atoi ( argv [1]) ;
66 if ( num < 100)
67 printf (" Less than 100.\ n ") ;
68 else
69 printf (" Greater than or equal to 100.\ n ") ;
70 }
71 $ gcc - Wall - Werror test2 .c -o test2
72 $ ./ run_steps . sh ./ test2 97 104 2 output3 . txt
73 $ echo $?
74 0
75 $ cat output3 . txt
76 === 97 ===
77 Less than 100.
78 === 99 ===
79 Less than 100.
80 === 101 ===
81 Greater than or equal to 100.
82 === 103 ===
83 Greater than or equal to 100.
84 $ ./ run_steps . sh ./ test2 97 104
85 Usage : ./ run_steps . sh [ executable ] [ start ] [ end ] [ step ] [ outfile ]
86 $ echo $?
87 1
88 $
5.3 Part #3: Templated Linked List
Filenames: list.hpp and list.inl
Look at the files list.hpp and list.inl that are provided on Canvas. These files contain the incomplete definition of a
templated linked list. You are to implement this class’ methods. In the header file, I describe what each method is supposed
to.
You are not allowed to use smart pointers in this assignment. (We will talk about these in slide deck #13.)
Manual review: I will do a quick manual review of your submission after the deadline in order to check that you obey
the time complexity constraints (where applicable), that you do not use smart pointers, and that you do not have public
member variables in class List.
Suggestions/tips:
• Recommended order of completion: I would probably start with the constructor, pushFront(), pushBack(), and
operator<<. I would consider the copy constructor, copy assignment operator, and destructor to be the hardest parts.
• Required concepts: If you understand operator overloading, templates, and copy semantics well, then I would think
that this assignment should be comparable to programming assignment #5 (class UnweightedGraph) in difficulty, so make
sure to start by understanding the recent concepts.
• list.hpp vs. list.inl: Because list.inl is included in list.hpp, it isn’t important which functions you choose to define in
list.hpp vs. list.inl. I would recommend avoiding defining all of the required methods in one or the other; I think you
should get used to the syntax for both defining a method within the class (in list.hpp) and defining a method outside
4
the class (in list.inl). For operator<<, it did not seem that I could define it outside of class List, as the compiler seems
to put additional restrictions on a friend of a templated class; I could not find a workaround, but maybe there is one.
• Avoid duplicating code where possible: Certain methods and/or operators are so similar (e.g. pushBack() and
operator+=) that, probably, you should have one of them call the other.
• Template compiler error messages: If you ask any C++ programmer what the worst part of the language is, they
will likely say it’s the compiler error messages that you get when dealing with templates. The slightest mistake in dealing
with templates can generate a huge number of error messages, and this can occur even when you’re not explicitly using
templates (e.g. when you’re using std::string, which is a typedef for the templated class std::basic_string
usually the case, you want to start looking at the first error message (in case that one causes all of the other ones), but
this requires some scrolling. An alternative that I’ve sometimes found helpful is to do the command g++ ... 2>&1 | head,
where 2>&1 redirects the standard error (the compiler error messages) of the g++ command to standard output so that
it can be pipelined into head.
• Initializer list error messages: If a compiler error is generated by one of your constructor initializer lists, the
compiler (at least, g++) will flag the last line that the initializer list reaches. This only matters if you spread the
initializer list across multiple lines like I tend to, but it’s something to be aware of, because it can be deceiving if the
cause of the error has to do with something towards the beginning of the initializer list instead of the end.
Below are examples of how your code should behave. You can find main.cpp on Canvas.
1 $ cat main . cpp
2 # include " list . hpp "
3
4 struct X
5 {
6 X () { std :: cout << " Constructor !\ n "; }
7 ~X () { std :: cout << " Destructor !\ n "; }
8 };
9
10 int main ()
11 {
12 std :: cout << std :: boolalpha ;
13 List < int > lst ;
14 lst . pushBack (15) ;
15 lst . pushFront (33) ;
16 lst . pushFront (20) ;
17 lst . pushBack (50) ;
18 lst . pushFront (40) ;
19 lst += 80;
20 std :: cout << lst ;
21 std :: cout << lst . length () << ’\n ’;
22 std :: cout << " lst [3]=" << lst [3] << ’\n ’;
23 lst [2] = 90;
24 std :: cout << lst ;
25 std :: cout << " Contains 50: " << lst . contains (50) << ’\n ’
26 << " Contains -10: " << lst . contains ( -10) << ’\n ’;
27 std :: cout << " Remove 50: " << lst . remove (50) << ’ ’ << lst ;
28 std :: cout << " Remove 80: " << lst . remove (80) << ’ ’ << lst ;
29 std :: cout << " Remove -10: " << lst . remove ( -10) << ’ ’ << lst ;
30 lst . pushFront (200) ;
31 lst . pushBack (300) ;
32 lst += 100;
33 std :: cout << lst ;
34 lst . remove (200) ;
35 lst -= 40;
36 std :: cout << lst ;
37 std :: cout << " Copy construction ...\ n ";
38 List < int > lst2 { lst };
39 lst2 . remove (90) ;
40 std :: cout << lst << lst2 ;
41 std :: cout << " Copy assignment ...\ n ";
42 lst2 = lst ;
43 std :: cout << lst << lst2 ;
44 lst . pushBack ( -400) ;
45 lst2 . pushFront ( -100) ;
46 lst2 += -200;
47 std :: cout << lst << lst2 ;
48 std :: cout << lst . length () << ’ ’ << lst2 . length () << ’\n ’;
49
50 std :: cout << " Trying strings ...\ n ";
51 List < std :: string > strings ;
5
52 std :: cout << strings ;
53 std :: cout << strings . length () << ’\n ’;
54 strings . pushBack (" def ") ;
55 strings . pushFront (" abc ") ;
56 strings += " ghi ";
57 std :: cout << strings ;
58 std :: cout << strings . length () << ’\n ’;
59 strings -= " gh ";
60 strings -= " abc ";
61 std :: cout << " After removing \" abc \": " << strings ;
62 std :: cout << strings . length () << ’\n ’;
63 strings . pushFront (" jklmn ") ;
64 std :: cout << strings ;
65 std :: cout << strings [2] << ’\n ’;
66 std :: cout << " Copy construction ...\ n ";
67 auto strings2 = strings ;
68 std :: cout << strings [1] << ’ ’ << strings2 [1] << ’\n ’;
69 strings . remove (" def ") ;
70 strings2 . pushFront (" op ") ;
71 std :: cout << " strings : " << strings
72 << " strings2 : " << strings2 ;
73 std :: cout << " strings [1]: " << strings [1] << ’\n ’
74 << " strings2 [1]: " << strings2 [1] << ’\n ’;
75
76 std :: cout << " Trying class X ...\ n ";
77 List
78 objs . pushBack (X {}) ;
79 std :: cout << " Trying out -of - range index ...\ n ";
80 try
81 {
82 auto o = objs [3];
83 }
84 catch ( const std :: out_of_range & ex )
85 {
86 std :: cerr << "I accept your exception !\ n ";
87 }
88 catch (...)
89 {
90 std :: cerr << " Wrong type of exception !\ n ";
91 }
92
93 std :: cout << std :: noboolalpha ;
94 }
95 $ g ++ - Wall - Werror main . cpp
96 $ ./ a. out
97 40 20 33 15 50 80
98 6
99 lst [3]=15
100 40 20 90 15 50 80
101 Contains 50: true
102 Contains -10: false
103 Remove 50: true 40 20 90 15 80
104 Remove 80: true 40 20 90 15
105 Remove -10: false 40 20 90 15
106 200 40 20 90 15 300 100
107 20 90 15 300 100
108 Copy construction ...
109 20 90 15 300 100
110 20 15 300 100
111 Copy assignment ...
112 20 90 15 300 100
113 20 90 15 300 100
114 20 90 15 300 100 -400
115 -100 20 90 15 300 100 -200
116 6 7
117 Trying strings ...
118
119 0
120 abc def ghi
121 3
122 After removing " abc ": def ghi
123 2
124 jklmn def ghi
125 ghi
6
126 Copy construction ...
127 def def
128 strings : jklmn ghi
129 strings2 : op jklmn def ghi
130 strings [1]: ghi
131 strings2 [1]: jklmn
132 Trying class X ...
133 Constructor !
134 Destructor !
135 Trying out - of - range index ...
136 I accept your exception !
137 Destructor !
138 $ valgrind ./ a . out > / dev / null
139 ...
140 ==3198== All heap blocks were freed -- no leaks are possible
141 ==3198==
142 ==3198== For counts of detected and suppressed errors , rerun with : -v
143 ==3198== ERROR SUMMARY : 0 errors from 0 contexts ( suppressed : 0 from 0)
144 $
7