-1

How can I delete all the pointer in my vector before that I going to copy to my vector new pointers (in case of const object)?

class Element {
    int val;
public:
    Element(int val) :
            val(val) {
    }
};

class MyClass {
    vector<Element*> v;

    static void FreeMemory(vector<Element*>& vec) {
        for (unsigned int i = 0; i < vec.size(); i++) {
            delete vec[i];
        }
    }

public:
    MyClass() = default;
    MyClass(const MyClass& mc) {
        //...
    }
    MyClass& operator=(const MyClass& mc) {
        if (this == &mc) {
            return *this;
        }
        //...
        FreeMemory(mc.v); //**error** - how can I delete the memory of any Element?
        //...
        return *this;
    }
    // ....
    // ....
};   

binding 'const std::vector' to reference of type 'std::vector&' discards qualifiers

Can I fix it with smart_pointers?

J.Roe
  • 73
  • 1
  • 8
  • 2
    You don't want to modify the right hand side of an assignment in the first place. The const qualifier in `const MyClass&` is there for a reason. Also, consider switching to managed pointers. – lubgr Jun 17 '18 at 19:43
  • @lubgr Can you explain me please how can I treat it with smart pointers? – J.Roe Jun 17 '18 at 19:46
  • Possible duplicate of [What are the basic rules and idioms for operator overloading?](https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-and-idioms-for-operator-overloading) – Richard Critten Jun 17 '18 at 19:47
  • @J.Roe Wait, before thinking about smart pointers: why do you want to store the elements as pointers anyhow? `Element` is has no virtual methods, you won't derive from it. Store them as `std::vector`, then go with compiler-generated special member functions. – lubgr Jun 17 '18 at 19:53
  • @lubgr You right, but I want later to make this class as abstract class, so I need to work with pointers. – J.Roe Jun 17 '18 at 19:56
  • As @lubgr noted in his first comment, you should not be replacing the content of the right hand operand (`mc`) of the assignment. Instead you should replace the contents of the left hand operand (`*this`), which probably will involve a `FreeMemory(v)` (or if you like to be explicit, `FreeMemory(this->v)`. – Ben Voigt Jun 17 '18 at 19:58
  • @BenVoigt Ok , I fixes it by this comment, and you know maybe how can I work here with smart_pointers? – J.Roe Jun 17 '18 at 20:02

1 Answers1

1

Here is a sketch of a class owning a std::vector of Element objects managed by std::unique_ptr. Not fully worked out, but it might work as a starting point.

class Element {
    int val;

public:
    explicit Element(int val) : val(val) {}
    virtual ~Element() = default;

    /* Subclasses must implement this method: */
    virtual std::unique_ptr<Element> clone() const = 0;
};

class ExclusivelyOwning {
    private:
        std::vector<std::unique_ptr<Element>> v;

    public:
        ExclusivelyOwning() = default;
        ExclusivelyOwning(const ExclusivelyOwning& other) {
            v.reserve(other.v.size());

            for (const auto& element : other.v)
                v.push_back(element->clone());
        }
        ExclusivelyOwning& operator=(const ExclusivelyOwning& rhs) {
            /* Use copy-swap idiom, not shown here. */
            return *this;
        }

        ExclusivelyOwning(ExclusivelyOwning&&) = default;
        ExclusivelyOwning& operator = (ExclusivelyOwning&&) = default;
        ~ExclusivelyOwning() = default;
};   

Note that copying an object with references to abstract classes (as Element in the code above) requires further techniques to render the copying meaningful. Here, I used a "virtual constructor" - the clone method.

lubgr
  • 37,368
  • 3
  • 66
  • 117
  • Using `shared_ptr` is even simpler, no need for handling special member functions. But that changes the ownership claims of your class to not having any. When you copy the object, the `Element` references point to the same object in both the copied-from and the newly created `MyClass` instance. – lubgr Jun 17 '18 at 20:19