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 turn: 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.