Skip to content

Lab 4 Assignment

CT 301 Lab 4

CT 301: C++ Fundamentals · Summer 2026
Lab 4: Templates and the Rule of 5/7
Source: learncpp.com · Instructor: Dr. Francisco R. Ortega

Overview

This is an explore-and-reflect lab. The goal is to learn by trying things, not to finish a polished homework. You will read the lessons and do the quiz questions they include (learncpp shows the solutions), then explore three programs: making a class into a template, giving a class that owns memory a correct deep copy, and adding move. Together the copy constructor, copy assignment, move constructor, and move assignment are the heart of the "rule of five" (you will also hear "rule of seven," which adds swap and a default constructor). When you are done, you record a short video explaining what you tried. There is no written report.

A note on style: the lecture slides use import std;. In this class, and in these labs, we will use #include (for example, #include <iostream>). Both are valid modern C++.
Why this matters for Homework 2. Your vector is a class template (Vector<T>), and because it owns a buffer, it must define its own copy constructor, copy assignment, move constructor, and move assignment. Getting those right, a real deep copy and a clean move, is most of the assignment. This lab is the same ideas in miniature.

Reading and Quiz

Read these lessons on learncpp.com. Several end with a Quiz time that includes a worked solution; do those and check yourself.

Lesson 11.6: Function templates
Writing one function that works for many types.
Lesson 13.13: Class templates
Writing one class that works for many types, like your Vector.
Lesson 14.14: Introduction to the copy constructor
The function that runs when an object is copied.
Lesson 21.12: Overloading the assignment operator
The function that runs when you assign one existing object to another.
Lesson 21.13: Shallow vs. deep copying
Why a class that owns memory needs its own copy, not a shared pointer.
Lesson 22.3: Move constructors and move assignment
Stealing resources instead of copying them, and what std::move does.
Lesson 21.9: Overloading the subscript operator
Writing operator[] so v[i] works on your own class.

Explore 1: make a class into a template

The Box below holds one int. Turn it into a template so it can hold any type. The main() already tries to use it with an int and a std::string; it will compile once Box is a template.

#include <iostream>
#include <string>

// TODO: make Box a template so it works for ANY type T, not just int.
// (Add  template <typename T>  above the class, and replace int with T.)
class Box {
public:
    Box(int value) : value_(value) {}
    int get() const { return value_; }
    void set(int value) { value_ = value; }
private:
    int value_;
};

int main() {
    Box<int> a(42);                 // these compile only after you templatize Box
    Box<std::string> b("hello");
    std::cout << a.get() << " " << b.get() << "\n";   // expect: 42 hello
    return 0;
}
Try. Add template <typename T> and replace int with T. Run it (expect 42 hello). Then make a Box<double> and print it too.

Explore 2: deep copy

IntArray owns a buffer. As written it has no copy constructor, so the compiler copies the pointer (a shallow copy): the copy and the original share one buffer. Run it first and see a[0] change to 99 when you only meant to change b, and (with -fsanitize=address) a double-free at the end. Then add a deep copy to fix it.

#include <iostream>

class IntArray {
public:
    IntArray(int n) : data_(new int[n]), size_(n) {
        for (int i = 0; i < n; ++i) data_[i] = 0;
    }
    ~IntArray() { delete[] data_; }

    // TODO: add a copy constructor and a copy assignment operator that make a
    // DEEP copy (allocate a new buffer and copy the elements), so that two
    // IntArrays never share the same buffer.

    int& at(int i) { return data_[i]; }
    int  size() const { return size_; }
private:
    int* data_;
    int  size_;
};

int main() {
    IntArray a(3);
    a.at(0) = 10; a.at(1) = 20; a.at(2) = 30;
    IntArray b = a;        // copy; with a DEEP copy, b gets its own buffer
    b.at(0) = 99;          // this must NOT change a
    std::cout << "a[0] = " << a.at(0) << " (should stay 10)" << std::endl;
    std::cout << "b[0] = " << b.at(0) << " (should be 99)" << std::endl;
    return 0;
}
Try. Run it as is with -fsanitize=address and watch the double-free. Then add a copy constructor and copy assignment that allocate a new buffer and copy the elements. Now a[0] stays 10 and there is no error.

Explore 3: move

Copying a big buffer is expensive. A move instead steals the buffer from a temporary or an object you no longer need, leaving the source empty. Add a move constructor and move assignment to your IntArray from Explore 2.

// Add these two to your IntArray from Explore 2.

// Move constructor: take other's buffer, then leave other empty.
IntArray(IntArray&& other) noexcept {
    // TODO: copy other's data_ and size_ into this, then set
    //       other.data_ = nullptr and other.size_ = 0
}

// Move assignment: free what you hold, take other's buffer, leave other empty.
IntArray& operator=(IntArray&& other) noexcept {
    // TODO
    return *this;
}

Then test it with this main():

#include <utility>   // std::move

int main() {
    IntArray a(3);
    a.at(0) = 10;
    IntArray c = std::move(a);   // move: c steals a's buffer
    std::cout << "after move, a.size() = " << a.size() << " (expect 0)\n";
    std::cout << "c[0] = " << c.at(0) << " (expect 10)\n";
    return 0;
}
Try. Run it. After the move, a.size() is 0 (its buffer is gone) and c holds the data. Why is moving cheaper than copying here?

Reflect and Record

Record a short video (about 3 to 5 minutes) and upload it to YouTube as Unlisted. In it:

This is a reflection, not a presentation. Rough is fine. There is no need to use AI, as you are graded on effort and on showing your own exploration. If you get stuck, you can say so in the video and still get the grade.

Grading

Labs are graded as complete or incomplete.

Full credit
You explored the three programs in a compiler and recorded a short video that shows your work and explains the ideas in your own words.
Zero
No submission, or no real try.

The labs together are worth 5 percent of your course grade.

How to Submit

Upload your video to YouTube as Unlisted, and submit the link (paste it into the Canvas assignment). Make sure the link is Unlisted, not Private, or we cannot view it. Make sure you do not use your phone. Produce a video with your face and the screen showing what you learned. 5 minutes is more than enough. 

Appendix: Online C++ Compilers

Any of the tools below will run the reading examples in your browser, with no local setup. Remember to use #include online, not import std;.

Our course toolchain is GCC 15.2 with -std=c++26. Only Compiler Explorer lets you set that exact combination. The other tools run an older fixed compiler, which is fine for these basic examples.

Compiler Explorer (godbolt.org) RECOMMENDED
The best match for our course. Lets you pick the exact compiler and see results and assembly.
How to use:
  1. In the compiler dropdown, choose x86-64 gcc 15.2.
  2. In the Compiler options box, type -std=c++26.
  3. To run the program (not just compile it), open the Execution or Add tool > Executor pane.
  4. Use the Share button to get a link to your code.
Python Tutor (pythontutor.com)
Best for seeing what your code does. It steps through line by line and shows variables and memory. Very useful in later labs on pointers.
How to use:
  1. Select C++ from the language menu.
  2. Type your code and press Visualize Execution.
  3. Step forward and back to watch values change.
Note: it runs an older fixed compiler, so you cannot set GCC 15.2 or -std=c++26 here. That is fine for the basic examples.
OnlineGDB (onlinegdb.com)
A simple editor with a real step-through debugger, good for watching a program run one line at a time.
How to use:
  1. Set the language (top right) to C++.
  2. Use the settings gear to pick the C++ standard.
  3. Press Run, or Debug to step through the code.
Note: older fixed GCC, may not offer c++26. Fine for the basic examples.
Wandbox (wandbox.org)
The quickest paste and run, with a shareable link.
How to use:
  1. Pick the newest GCC from the compiler list.
  2. Choose C++26 from the standard menu, or add -std=c++26 to the options.
  3. Press Run, then Share for a link.