Skip to content

Instantly share code, notes, and snippets.

@israelchen
Last active May 12, 2023 17:46
Show Gist options
  • Select an option

  • Save israelchen/123f9d398fafbebf728a to your computer and use it in GitHub Desktop.

Select an option

Save israelchen/123f9d398fafbebf728a to your computer and use it in GitHub Desktop.
Ownership semantics for pointers in C++
#include <iostream>
#include <memory>
using namespace std;
class Resource {
public:
Resource(string id) : _id(id) {
cout << "Resource::Resource(" << _id << ")" << endl;
}
~Resource() {
cout << "Resource::~Resource(" << _id << ")" << endl;
}
void Speak() {
cout << "Resource::Speak(" << _id << ")" << endl;
}
private:
string _id;
};
class ResourceBuilder {
public:
ResourceBuilder() {
cout << "ResourceBuilder::ResourceBuilder()" << endl;
}
~ResourceBuilder() {
cout << "ResourceBuilder::~ResourceBuilder()" << endl;
}
unique_ptr<Resource> Build(string id) {
return unique_ptr<Resource>(new Resource(id));
}
shared_ptr<Resource> BuildShared(string id) {
return shared_ptr<Resource>(new Resource(id));
}
};
class ResourceConsumer {
public:
ResourceConsumer() {
cout << "ResourceConsumer::ResourceConsumer()" << endl;
}
~ResourceConsumer() {
cout << "ResourceConsumer::~ResourceConsumer()" << endl;
}
void ConsumeWithoutOwnership(Resource* const resource) {
resource->Speak();
}
void ConsumeWithOwnership(const unique_ptr<Resource> resource) {
resource->Speak();
}
void ConsumeWithSharedOwnership(const shared_ptr<Resource> resource) {
resource->Speak();
}
};
int main(int argc, char* argv[]) {
/*
Output:
ResourceBuilder::ResourceBuilder()
Resource::Resource(resource1)
Resource::Resource(resource2)
Resource::Resource(resource3)
ResourceConsumer::ResourceConsumer()
Resource::Speak(resource1)
Resource::Speak(resource2)
Resource::~Resource(resource2)
Resource::Speak(resource3)
Resource::Resource(resource4)
Resource::Speak(resource4)
Resource::~Resource(resource4)
-- main going out of scope --
ResourceConsumer::~ResourceConsumer()
Resource::~Resource(resource3)
Resource::~Resource(resource1)
ResourceBuilder::~ResourceBuilder()
*/
unique_ptr<ResourceBuilder> builder(new ResourceBuilder);
auto resource1 = builder->Build("resource1");
auto resource2 = builder->Build("resource2");
auto resource3 = builder->BuildShared("resource3");
unique_ptr<ResourceConsumer> consumer(new ResourceConsumer);
consumer->ConsumeWithoutOwnership(resource1.get()); // raw pointer (ownership not assumed)
consumer->ConsumeWithOwnership(std::move(resource2)); // lvalue, have to be moved
consumer->ConsumeWithSharedOwnership(resource3); // shared
consumer->ConsumeWithOwnership(builder->Build("resource4")); // rvalue
cout << "-- main going out of scope --" << endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment