I have a class that represents a file in specific binary format on disk (the parent in the title) and another class that represents an object inside that file (child). When the object changes, it sometimes needs to relocate to a new position in the file and the file class has to be notified about this new position.
To do this, I have added a weak_ptr
field to object, which points to the file. Except that means there has to be a shared_ptr
for file, so I'm using a static
factory method instead of public constructor for it. And object now can't be initialized in the constructor, so I'm using unique_ptr
for it.
In code, it looks something like this:
class File;
class Object
{
private:
std::weak_ptr<File> file;
public:
Object(std::weak_ptr<File> file)
: file(file)
{}
void modify();
};
class File
{
private:
std::unique_ptr<Object> object;
std::shared_ptr<File> self;
File()
{}
public:
void setObjectPosition(std::uint64_t newPosition);
static std::shared_ptr<File> create();
};
void Object::modify()
{
std::uint64_t newPosition = …;
file.lock()->setObjectPosition(newPosition);
}
void File::setObjectPosition(std::uint64_t objectPosition)
{
// store objectPosition
}
std::shared_ptr<File> File::create()
{
auto file = std::shared_ptr<File>(new File());
file->self = file;
file->object = std::unique_ptr<Object>(new Object(file));
return file;
}
Is this this the right approach to do this? Or is there a better/more idiomatic solution? I feel like I'm using *_ptr
too much, but I can't think of anything better.
Best Answer
If all you need is a non-owning pointer to an object, just use a raw pointer. Here's a smaller example:
shared_ptr
andunique_ptr
imply some kind of ownership, which child->parent does not have, since the parent owns the child. Therefore a raw pointer is totally okay in this situation(just don'tdelete
it!)