Mixing Smart and Raw Pointers
Is it okay to mix smart pointers and raw pointers in the same program?
Yes, it is common and often necessary to mix smart pointers and raw pointers in the same program. The key is to establish clear conventions around ownership and responsibility.
When a function uses a raw pointer, it is typically signaling that it wants access to the resource, but is not taking ownership of it. For example:
#include <memory>
#include <iostream>
void PrintName(std::string* Name) {
std::cout << *Name << '\n';
}
int main() {
auto Name{std::make_unique<std::string>(
"Gandalf")};
PrintName(Name.get());
}
Gandalf
Here, main
is maintaining ownership of the resource, and PrintName
is simply accessing it.
Conversely, when ownership needs to be transferred, smart pointers are used:
#include <memory>
#include <utility>
#include <iostream>
void StoreNameElsewhere(std::unique_ptr<
std::string> Name) {
// Store name in file, database etc
std::cout << "Storing " << *Name << "\n";
}
int main() {
auto Name{std::make_unique<std::string>(
"Gandalf")};
StoreNameElsewhere(std::move(Name));
}
Storing Gandalf
In summary:
- Use smart pointers for ownership
- Use raw pointers for non-owning access
- Be clear about whether a function is taking ownership or not
- Don't delete resources you don't own
Smart Pointers and std::unique_ptr
An introduction to memory ownership using smart pointers and std::unique_ptr
in C++