Reputation: 738
Motivation
Imagining that there is a very large class A
, and I wanna store it in a vector and I also want the vector to be copyable. Thus, smart pointer like std::shared_ptr
and std::unique_ptr
would not be nice choices. I know I could store objects of A
in std::vector<A>
directly. But as I said, A
is a very large class. And since elements of std::vector<A>
reside continuously in memory, there is a big chance that std::vector<A>
needs to reallocate memory if I update it frequently. So, I need a "smart pointer" (let's say copyable_ptr
) which will copy the underlying resource when copying the smart pointer itself. Then I could use std::vector<copyable_ptr<A>>
to manage objects of A
.
Here is a snippet template class of copyable_ptr
:
template <typename T> class copyable_ptr {
public:
explicit copyable_ptr(T *p) : p(p) {}
copyable_ptr(copyable_ptr const &rhs) : p(new T(*rhs.p)) {}
copyable_ptr(copyable_ptr &&rhs) : p(rhs.p) { rhs.p = nullptr; }
~copyable_ptr() { delete p; }
copyable_ptr &operator=(copyable_ptr rhs) {
swap(rhs);
return *this;
}
void swap(copyable_ptr &rhs) {
using std::swap;
swap(p, rhs.p);
}
T &operator*() const { return *p; }
T *operator->() const { return &this->operator*(); }
/* other members */
private:
T *p;
};
template <typename T>
inline void swap(copyable_ptr<T> &lhs, copyable_ptr<T> &rhs) {
lhs.swap(rhs);
}
Question
Is there similar class that I can use directly or should I write my own or Is there any other appropriate solutions to store big class in container?
Edit
I think I should explain myself more clearly. A
is a very large class, and I wanna use std::vector
to manage objects of A
. Basically, there are four options to do the job:
std::vector<std::shared_ptr<A>> a1; // #1
std::vector<std::unique_ptr<A>> a2; // #2
std::vector<A *> a3; // #3
std::vector<A> a4; // #4
I do not want to share objects of A
, which makes #1 inappropriate. The vector will not be copyable in #2, and I have to take care of memory management manually
in #3. So, only #4 lefts.
However, what I don't like about #4 is when size of a4
reaches its capacity, reallocating happens. Double size of a4
will be reserved (as I said, A
is a very large class, isn't it inappropriate to reserve so much continuous memory in heap just for potential usage?). And What's worse is we perhaps need to move every single element of a4
to the newly allocated memory from old memory location. Another backward of #4 that I forgot to mention when I asked the question is it's not polymorphic support.
So, if I use std::vector<copyable_ptr<A>>
to manage objects of A
, all the problems I mentioned above seems be handled properly. All you need is a well designed copyable_ptr
class, and that's what I'm looking for.
Upvotes: 3
Views: 616
Reputation: 559
Not exactly the answer to question, but if this:
However, what I don't like about #4 is when size of a4 reaches its capacity, reallocating happens.
is your main concern and if your are Ok with storing your classes in non-contiguous memory with slightly slower direct access by index, you can use std::deque
instead of std::vector
.
Upvotes: 0
Reputation: 1693
As far as I know, there is no such smart pointer in the standard library. Your copyable_ptr seems to do the job. I've used such things in the past, though for polymorphic classes instead of just really big classes.
Upvotes: 1
Reputation: 118435
Yes, there is such a thing: it's called the class itself.
The whole purpose of a smart pointer is to provide a reference-counted handle for an object, that can be passed around, without copying the underlying object, and automatically destroy the object when the reference count goes down to 0, and the last smart pointer referencing the object goes out of scope, and it gets destroyed (with certain variations of reference-counting semantics between shared_ptr
, unique_ptr
, et al).
If you want to have some kind of a pointer to an object that copies it, when copying the pointer, you don't need a pointer for that. Just use the object directly, by value. Every time you copy it, you're guaranteed to copy the object, by definition.
Having some kind of pointer, around, adds absolutely nothing of value. You want to use the object directly, copy it when needed, etc... Just use the object.
Upvotes: 3