Question

I have a abstract base class that hold data, and I need allocate memory to these data, and the other problem is that derivate class has the = operator overloaded and copy constructor, I would like to know how Can I assure that in the derivate class copy the members data from abstract base class will be copied too, follows the code exemple:

class A {
public:
  A(const char* v) {
    value = new char[strlen(v)+1];
    strncpy(value, v, strlen(v));
  }

  A(const A &a) {
    value = new char[strlen(a.value)+1];
    strncpy(value, a.value, strlen(a.value));
  }

  virtual ~A() {
    delete[] value;
  }

  A& operator=(const A& a) {
    value = new char[strlen(a.value)+1];
    strncpy(value, a.value, strlen(a.value));
    return *this;
  }

  const char* get() const {
    return value;
  }

  virtual void do_some() = 0;
private:
  char *value;
};

class B: public A {
public:
  B(const char *v, const char *n) : A(v) {
    name = new char[strlen(n)+1];
    strncpy(name, n, strlen(n));
  }

  B(const B &b) : A(b) {
    name = new char[strlen(b.name)+1];
    strncpy(name, b.name, strlen(b.name));
  }

  ~B() {
    delete[] name;
  }

  B& operator=(const B& b) {
    A::operator=(b);
    name = new char[strlen(b.name)+1];
    strncpy(name, b.name, strlen(b.name));
    return *this;
  }

  const char *get() const {
    return name;
  }

  void do_some() {
    std::cout << name << std::endl;
  }

private:
  char *name;
};

My doubts is, in some C++'s books says that is not a good idea to overload the operator = and declare a copy constructor in abstract base class, so how can I declare a copy constructor and operator= in derivate class and assure that the base class was copied properly?

In my project if I don't use data members at the abstract base class, I have to declare some data members in all derivate class, of course that is more than one, so I designed the abstract class with data member, but I don't know if is the better way to do.

Was it helpful?

Solution

What you're doing is a little awkward, but technically fine (except for leaking memory by not deleting name and value in the assignment operator before new[]-ing it), however only if you have no plans for multiple inheritance. That gets a bit messy, and may be why whatever books you're referring to are warning against it, but you shouldn't be using multiple inheritance (in general, but especially) on classes with data members anyways.

You might want to try a different approach regardless. Consider using a protected helper function (or a few) in the base class to set its variables:

class A
{
public:

// ...

private:
  char *value;

protected:
  void set_value(const char *str)
  {
    delete[] value; // remember, deleting null does nothing
    value = new char[strlen(str)+1];
    strncpy(value, str, strlen(str)); // Also, why do you need strncpy?
    // You'll get no null-terminator, which leads to major problems
    // Consider just strcpy(value, str);
  }
};

This way, you can set that value from any derived class, the functionality is still hidden from public use, and you don't have to write an assignment operator or copy constructor for an abstract class. Which, when you think about it, really doesn't make much sense, does it?

It also saves you from this:

A *a = new B;

B *b = new B;
(*a) = (*b); // ...with an assignment operator on A, this should compile.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top