Class derived from class instance?

advertisements

how do I make a derived class which can change all the variables from an instance of its base class? I understand I could declare the base class variables static, but when I do that I cannot initialise them using functions, which makes the code very message and difficult to edit.

This an example class; why does c2 not edit x in the theC1 class. If it is referencing to a c1 class which is not theC1, then what is is referencing to?

#include <stdio.h>

class c1
{
public:
    c1( int d )
    {
        x = d;
    }
    int x;
};

class c2 : public c1
{
public:
    c2( c1& ref )
        :
    c1( ref )
    {};
    void setx()
    {
        x = 5;
    }
};

int main ()
{
    c1 theC1(4);
    c2 theC2(theC1);
    theC2.setx();

    printf( "%d\n",theC1.x );
    printf( "%d\n",theC2.x );

    return 0;
}


theC1 and theC2 are completely separate instances. theC2 contains a subobject of type c1 which is initialised by the reference ref, but it's still (and always will be) a different instance of c1 than theC1. The base class subobject is a member of every c2 instance and there's no way to make this "shared" with any other instance of c2 or c1.

You could store the reference inside c2 and access that instead of deriving from c1 if that is the semantics you're after. The code would then look like this:

class c1
{
public:
    c1( int d )
    {
        x = d;
    }
    int x;
};

class c2
{
    c1 &myC1;
public:
    c2( c1& ref )
        :
    myC1(ref)
    , x(myC1.x)
    {}
    void setx()
    {
        myC1.x = 5;
    }
    int &x;
};

Of course, it would be better to encapsulate x, rather than have it public and have to resort to reference tricks like those in the code above.

UPDATE

One way to implement this on a larger scale could be c1 and c2 implementing the same interface, and c2 instances sharing a "data instance" of c1:

#include <memory>

struct c1_iface
{
  virtual int getX() const = 0;
  virtual void setX(int newX) = 0;
};

class c1 : public c1_iface
{
  int x;

public:
  virtual int getX() const { return x; }
  virtual void setX(int newX) { x = newX; }
};

class c2 : public c1_iface
{
  std::shared_ptr<c1> data_;

public:
  explicit c2(std::shared_ptr<c1> data) : data_(data) {}

  virtual int getX() const { return data_->getX(); }
  virtual void setX(int newX) { data_->setX(newX); }
};

If you don't have access to C++11, you can use boost::shared_ptr instead (or just use manual sharing, not really recommended).

As a slightly dirtier alternative, you could move the shared pointer (or its equivalent) into c1_iface and make the functions non-abstract, dereferencing it.