Deep copying vector of pointers to fewer objects

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.
Last edited on
The clear answer: It depends.

Whether or not you need to share or copy the object depends on what you want to do with them later on. The name Object does not contain any hint how it is used.
1
2
3
4
5
6
for K in range(len(v)):
    index = find(v[K], v[0:K]) //looking for a "shared" object on the left part of the vector
    if not index:
        other.v.push( this->v[K]->clone() ) //a new one, deep copy
    else:
        other.v.push( other.v[index] ) //already there, so just linking 

this will end up being O(n^2), but you may optimise the `find()' function
Topic archived. No new replies allowed.