14.14. Coding PracticeΒΆ
Question
Below is the struct definition for room, which has a length,
width, and height. It also has two member functions, calculate_area
and calculate_volume. Turn this struct into a class with
private member variables.
1#include <iostream>
2
3// Turn the struct definition of room into a class definition.
4struct room {
5 int length;
6 int width;
7 int height;
8
9 int calculate_area () {
10 return length * width;
11 }
12
13 int calculate_volume () {
14 return length * width * height;
15 }
16};
Answer
Below is the class definition of room. As you can see, there isn't
a big difference between structs and classes.
1#include <iostream>
2
3class room {
4 private:
5 int length;
6 int width;
7 int height;
8
9 public:
10 int calculate_area () {
11 return length * width;
12 }
13
14 int calculate_volume () {
15 return length * width * height;
16 }
17};
Practice selection
The legacy Runestone question pool c192_cp_14_ac_2_sq is represented by these exercises:
Question
Below is the class definition for temp. Write
the private member functions c_to_f and f_to_c,
which converts Celsius to Fahrenheit and vice versa
and returns the conversion. Update get_fahrenheit
and so that if is_celsius is
true and a user calls get_fahrenheit, it will
call c_to_f and return the correct temperature
in degrees Fahrenheit. Do the same for get_celsius.
1#include <iostream>
2
3class temp {
4 private:
5 double fahrenheit;
6 double celsius;
7 bool is_fahrenheit;
8 bool is_celsius;
9
10 // Write your implementation of c_to_f here.
11
12 // Write your implementation of f_to_c here.
13
14 public:
15 double get_fahrenheit () { return fahrenheit; }
16 double get_celsius () { return celsius; }
17 void set_fahrenheit (double f) { fahrenheit = f; is_fahrenheit = true; is_celsius = false; }
18 void set_celsius (double c) { celsius = c; is_celsius = true; is_fahrenheit = false; }
19 void print_temp () {
20 if (is_fahrenheit) {
21 std::cout << "It is " << get_fahrenheit() << " degrees Fahrenheit" << std::endl;
22 }
23 else {
24 std::cout << "It is " << get_celsius() << " degrees Celsius" << std::endl;
25 }
26 }
27};
Answer
Below is one way to implement this. We use the correct conversions
in c_to_f and f_to_c and then call these functions in
get_fahrenheit and get_celsius if needed.
1#include <iostream>
2
3class temp {
4 private:
5 double fahrenheit;
6 double celsius;
7 bool is_fahrenheit;
8 bool is_celsius;
9
10 double c_to_f() {
11 return celsius * 9/5 + 32;
12 }
13
14 double f_to_c() {
15 return (fahrenheit - 32) * 5/9;
16 }
17
18 public:
19 double get_fahrenheit () {
20 if (is_celsius) { return c_to_f(); }
21 else { return fahrenheit; }
22 }
23 double get_celsius () {
24 if (is_fahrenheit) { return f_to_c(); }
25 else { return celsius; }
26 }
27 void set_fahrenheit (double f) { fahrenheit = f; is_fahrenheit = true; is_celsius = false; }
28 void set_celsius (double c) { celsius = c; is_celsius = true; is_fahrenheit = false; }
29 void print_temp () {
30 if (is_fahrenheit) {
31 std::cout << "It is " << get_fahrenheit() << " degrees Fahrenheit" << std::endl;
32 }
33 else {
34 std::cout << "It is " << get_celsius() << " degrees Celsius" << std::endl;
35 }
36 }
37};
Practice selection
The legacy Runestone question pool c192_cp_14_ac_4_sq is represented by these exercises:
Question
We took a look at vectors in chapter 10, where we saw
how we could add data to the end of a vector and remove
data from the end of a vector. But what if we wanted to
add and remove things at the beginning of a vector? Or we wanted to
print out a vector without painfully constructing a
loop every time? We can create our own my_vector class!
Write the my_vector class, which has a vector of ints as a
private member variable. Also write the default constructor.
1#include <iostream>
2#include <vector>
3
4// Write the class definition for my_vector here.
Answer
Below is the class definition of my_vector. We use the public
and private keywords to separate public and private members of
our class. The default constructor sets size to 0.
1#include <iostream>
2#include <vector>
3
4class my_vector {
5 private:
6 std::vector<int> elements;
7
8 public:
9 my_vector() {};
10};
Practice selection
The legacy Runestone question pool c192_cp_14_ac_6_sq is represented by these exercises:
Question
The reason why we have elements as a private member variable is that
people using our my_vector class don't need to know how we implemented
our class, so we can implement it however we want.
This means for functions my_vector has that overlap with
functions that vector has, we can just call the same function
on our elements vector. Write the my_vector functions
size, push_back, pop_back, and at. size returns
the size of our my_vector. push_back takes an
int and adds it to the end of our my_vector. pop_back
removes the last element. at takes an index and returns the
data stored at that index. Use existing vector functions to
implement these my_vector functions!
1#include <iostream>
2#include <vector>
3
4class my_vector {
5 private:
6 std::vector<int> elements;
7
8 public:
9 my_vector() {};
10 my_vector(std::vector<int> vec);
11
12 // Write the size function here.
13
14 // Write the push_back function here.
15
16 // Write the pop_back function here.
17
18 // Write the at function here.
19};
20
21int main() {
22 std::vector<int> data = { 2, 4, 1, 5, 2, 6 };
23 my_vector my_vec(data);
24 std::cout << "The first element is " << my_vec.at(0) << std::endl;
25 my_vec.pop_back();
26 my_vec.pop_back();
27 my_vec.push_back(12);
28 std::cout << "The size of my_vec is " << my_vec.size() << std::endl;
29 std::cout << "The last three elements are " << my_vec.at(2) << ", "
30 << my_vec.at(3) << ", and " << my_vec.at(4) << std::endl;
31}
Answer
Below is one way to implement these functions. Since these
functions are defined for vectors, we can call them
on elements.
1#include <stdexcept>
2#include <cstddef>
3#include <iostream>
4#include <vector>
5
6class my_vector {
7 private:
8 std::vector<int> elements;
9
10 public:
11 my_vector() {};
12 my_vector(std::vector<int> vec);
13
14 std::size_t size() { return elements.size(); }
15 void push_back(int value) { elements.push_back(value); }
16 void pop_back() { if (elements.empty()) throw std::out_of_range("empty vector");
17 elements.pop_back(); };
18 int at(std::size_t index) { return elements.at(index); }
19};
20
21int main() {
22 std::vector<int> data = { 2, 4, 1, 5, 2, 6 };
23 my_vector my_vec(data);
24 std::cout << "The first element is " << my_vec.at(0) << std::endl;
25 my_vec.pop_back();
26 my_vec.pop_back();
27 my_vec.push_back(12);
28 std::cout << "The size of my_vec is " << my_vec.size() << std::endl;
29 std::cout << "The last three elements are " << my_vec.at(2) << ", "
30 << my_vec.at(3) << ", and " << my_vec.at(4) << std::endl;
31}
Practice selection
The legacy Runestone question pool c192_cp_14_ac_8_sq is represented by these exercises:
Question
Let's write the my_vector member function push_front and
pop_front. push_front should take a value and add it
to the front of our my_vector, and pop_front should
remove the first element.
1#include <stdexcept>
2#include <cstddef>
3#include <iostream>
4#include <vector>
5using std::cout;
6
7class my_vector {
8 private:
9 std::vector<int> elements;
10
11 public:
12 my_vector() {};
13 my_vector(std::vector<int> vec);
14
15 std::size_t size();
16 void push_back(int value);
17 void pop_back();
18 int at(std::size_t index);
19 void print();
20};
21
22// Write your implementation of push_front here.
23
24// Write your implementation of pop_front here.
25
26int main() {
27 std::vector<int> data = { 2, 14, 5 };
28 my_vector my_vec(data);
29 my_vec.pop_front();
30 my_vec.push_front(5);
31 my_vec.push_front(10);
32 cout << "The new size is " << my_vec.size(); << std::endl;
33 my_vec.print();
34}
Answer
Below is one way to implement these functions. For push_front, we can create a temporary vector and add the new element to the front before pushing the rest of the old elements to the back. For pop_front, we can shift all elements up by one index and pop the last element off.
1#include <stdexcept>
2#include <cstddef>
3#include <iostream>
4#include <vector>
5using std::cout;
6
7class my_vector {
8 private:
9 std::vector<int> elements;
10
11 public:
12 my_vector() {};
13 my_vector(std::vector<int> vec);
14
15 std::size_t size();
16 void push_back(int value);
17 void pop_back();
18 int at(std::size_t index);
19 void print();
20public:
21 void push_front(int value);
22 void pop_front();
23};
24
25void my_vector::push_front(int value) {
26 std::vector<int> temp;
27 temp.push_back(value);
28 for (std::size_t i = 0; i < elements.size(); ++i) {
29 temp.push_back(elements[i]);
30 }
31 elements = temp;
32}
33
34void my_vector::pop_front() {
35 for (std::size_t i = 1; i < elements.size(); ++i) {
36 elements[i - 1] = elements[i];
37 }
38 if (elements.empty()) throw std::out_of_range("empty vector");
39 elements.pop_back();
40}
41
42int main() {
43 std::vector<int> data = { 2, 14, 5 };
44 my_vector my_vec(data);
45 my_vec.pop_front();
46 my_vec.push_front(5);
47 my_vec.push_front(10);
48 cout << "The new size is " << my_vec.size() << std::endl;
49 my_vec.print();
50}
Practice selection
The legacy Runestone question pool c192_cp_14_ac_10_sq is represented by these exercises: