Step 3 of 5
Returning ownership
A function that creates an object on the heap should return a unique_ptr. Then the return type itself documents "you own this now", and the caller can't forget to delete it. In old C and C++ code, the same function would return a raw pointer and a comment saying "caller must free", which people forget.
A unique_ptr can also be empty. Returning nullptr is a clean way to say "I couldn't make one".
#include <iostream>
#include <memory>
#include <string>
struct Shape {
std::string kind;
double area;
};
std::unique_ptr<Shape> make_shape(const std::string& kind, double size) {
if (kind == "square") return std::make_unique<Shape>(Shape{kind, size * size});
if (kind == "circle") return std::make_unique<Shape>(Shape{kind, 3.14 * size * size});
return nullptr; // unknown kind: nothing to own
}
int main() {
for (const char* k : {"square", "hexagon", "circle"}) {
auto s = make_shape(k, 2);
if (s) {
std::cout << s->kind << " " << s->area << "\n";
} else {
std::cout << "can't make a " << k << "\n";
}
}
}
square 4
can't make a hexagon
circle 12.56
How it works
- Returning a
unique_ptrby value moves it to the caller automatically. Nostd::moveneeded onreturn. return nullptr;converts to an emptyunique_ptr.- The caller must check
if (s)before usings->.... Dereferencing an emptyunique_ptris undefined behavior, just like a null raw pointer.
Building the string
Your function returns a pointer to a new std::string. std::make_unique<std::string>("bomb " + site) constructs it from the concatenated text.
Your task
Write std::unique_ptr<std::string> make_callout(const std::string& site) that returns a new string "bomb " + site for sites A and B, and nullptr for anything else.
Challenge 2
Write std::unique_ptr<Weapon> buy(const std::string& name, int& money). Prices: ak47 2700, awp 4750, p250 300. If the weapon exists and money covers it, subtract the price and return a new Weapon. Otherwise return nullptr and leave money alone.
Challenge 3
A linked list can own its nodes with unique_ptr: each Node owns the next one, so deleting the head frees the whole chain. Write std::unique_ptr<Node> build(const std::vector<int>& v) that builds a list with the values in order (an empty vector gives nullptr), and int sum(const Node* head).