-1

I've got this code here:

class DerivedClass : public BaseClass {
    SomeClass* a1;
    Someclass* a2;
public:
    //constructors go here
    ~DerivedClass() { delete a1; delete a2;}
    // other functions go here ....
};

My first question is as follows:

  • Can I write an "operator=" to "DerivedClass" ? (if your answer is yes, could you show me how?)

My second question is:

  • If the answer to the above is yes, could you show me how to make a "copy consructor" using the "operator=" that you wrote beforehand (if that is even possible)?
5
  • 5
    Yes you can, and yes it is possible, but if we post the code for you you won't learn anything. Try yourself and post any problems you might have. Commented Jul 1, 2013 at 15:30
  • en.wikipedia.org/wiki/Rule_of_three_%28C%2B%2B_programming%29 Commented Jul 1, 2013 at 15:35
  • The usual pattern is to use the copy constructor in the assignment operator (copy and swap), not the other way around. Using the assignment operator in the copy constructor requires constructing the member variables before you can use the assignment operator, which is sub-efficient. Commented Jul 1, 2013 at 15:35
  • The reason i'm posting here is because I don't know how to implement it, so it would be very kind of you to show me how. Commented Jul 1, 2013 at 15:43
  • Looks like an interview question... Commented Jul 1, 2013 at 19:38

2 Answers 2

1

Here's the best way to write the copy constructor and assignment operator, respecting the "Rule of Zero":

#include <optional>
class DerivedClass : public BaseClass
{
    std::optional<SomeClass> a1;
    std::optional<SomeClass> a2;
public:
    //constructors go here
};

The compiler will write correct code for the destructor, copy constructor, and copy assignment operators. If SomeClass is movable, you'll get move assignment and move constructor for free as well.

If SomeClass is polymorphic, you will need a clone() function like BogoIt mentioned. But even in that case it's valuable to use a smart pointer (std::unique_ptr would be appropriate).

Sign up to request clarification or add additional context in comments.

4 Comments

Which standard defines header <optional>? It doesn't appear to be the ISO/IEC 14882:2011 (the C++11 standard). Tables 14 and 15 (p435, and reproduced in List of standard header files in C and C++) do not list <optional> as a header.
@Jonathan: oops, it's only in namespace std starting with the C++14 draft. Do you know a good C++11 alternative that's like std::unique_ptr but is copyable by copying the target object?
Succinctly, no — I haven't looked hard. Maybe Boost has a good one? (Version 1.54 was released today, 2013-07-01, to judge by my incoming email.)
@JonathanLeffler: If you're willing to pull in Boost, then boost::optional would be a candidate.
1

The body of copy ctor and op= depend on the way you plan to store your resources: a1 and a2 variables. If you need them to be copied to another class - you should write some function that will make a full copy of your SomeClass object. Another case - you can simply copy pointer value - but then be very careful about the way you use them and especially delete them. The easiest solution to the sharing resources problem would be using some smart pointer, for example boost::shared_ptr or c++11 std::shared_ptr.

So if you plan to copy your resources:

class DerivedClass : public BaseClass {
    SomeClass* a1;
    Someclass* a2;
public:

    // note: do not forget to assign zeroes to your pointers, unless  you use some kind of smart pointers
    DerivedClass()
    :a1(0), a2(0){}

    DerivedClass(const DerivedClass& d)
                :a1(0), a2(0)
    {
        *this = d;
    }

    DerivedClass& operator=(const DerivedClass& d)
    {
        if (this == &d)
            return *this;

        delete a1;
        a1 = d.a1->clone();

        delete a2;
        a2 = d.a2->clone();

        return *this;
    }


    //constructors go here
    ~DerivedClass() { delete a1; delete a2;}
    // other functions go here ....
};

You will also need SomeClass's clone() function, which going to copy your objects: class SomeClass { public:

    SomeClass* clone() const
    {
        return new SomeClass();
    }
};

6 Comments

your copy constructor has undefined behavior: delete a1 when a1 is not initialized.
Thank you for noting and fixing this silly bug.
That is better than downright downvoting it. I think this solution is fine.
@PhilipStuyck: It's not fine. It has undefined behavior for DerivedClass d{}; d = d;
ok, added self-assignment check
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.