I have been researching how best to implement a design I have in mind for a class, in which I need to have a container, that contains pointers to an object I will design myself later on. I haven't decided completely on what container or pointers to use (smart pointers or just *), but for now I'm going with a std::vector<std::shared_ptr<std::string>> for testing only, as both vector and string already does a deep copy rather than a shallow copy.
But I've discovered that deep copying a vector of pointers only copies the pointers and not the objects they point to. And that's what I need help figuring out a solution for.
However, it's not as simple as iterating the vector and copying/cloning each item and assigning them to a pointer in the new vector.
You see, there are fewer objects than there are pointers, meaning that some of the pointers will point to the same objects, i.e. sharing an object. When I invoke the vector's deep copy, I need to clone both the pointers and the objects, ensuring that those pointers still point to a copy of their shared object.
Here's a small example with strings, that I've been using to test this with.
Object.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
#ifndef OBJECT_H
#define OBJECT_H
#include <string>
#include <bitset>
#include <vector>
#include <memory>
using namespace std;
class Object
{
public:
Object();
virtual ~Object();
Object(const Object& other);
vector<shared_ptr<string>> v;
protected:
private:
};
#endif // OBJECT_H
| |
Object.cpp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
#include "Object.h"
Object::Object()
{
//ctor
string s = "1";
string t = "2";
v.push_back(make_shared<string>(s));
v.push_back(make_shared<string>(t));
v.push_back(make_shared<string>(s));
}
Object::~Object()
{
//dtor
}
Object::Object(const Object& other)
{
//copy ctor
v = other.v;
}
| |
main.cpp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
#include <iostream>
using namespace std;
#include "Object.h"
int main()
{
Object o1;
Object o2(o1);
(*o1.v[0])[0] = '3';
cout << *(o1.v[0]) << endl;
cout << *(o2.v[0]) << endl;
return 0;
}
| |
So the question is: How do I go about copying both pointers and objects in the stated way? Especially considering I'll later replace string with a class of my own, and that researching copy constructors and the virtual clone method has left me more confused than ever as I've seen claims that both are superior to the other and that both are to be preferred for deep copying.
It should be noted that the project is only intended for my own use, so I'm not really concerned with things like leaving slicing open and other things that might be abused by other users, as it will only be myself who runs the code I end up with.