theC1
и theC2
- полностью отдельные экземпляры. theC2
содержит подобъект типа c1
, который инициализируется ссылкой ref
, но он по-прежнему (и всегда будет) другим экземпляром c1
, чем theC1
. Субобъект базового класса является членом каждого экземпляра c2
, и нет никакого способа сделать этот «общий» с любым другим экземпляром c2
или c1
.
Вы можете сохранить ссылку внутри c2
и получить доступ к ней вместо c1
, если это семантика, которой вы пользуетесь. Код будет выглядеть следующим образом:
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;
};
Конечно, было бы лучше, чтобы инкапсулировать x
, а не его общественность и вынуждены прибегать к хитрости ссылаться как и в приведенном выше коде.
UPDATE
Один из способов осуществить это в большем масштабе может быть c1
и c2
реализации и тот же интерфейс, и c2
экземпляров разделяющих «экземпляр данных» 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); }
};
Если у вас нет доступа к C++ 11, вместо этого вы можете использовать boost::shared_ptr
(или просто использовать ручной обмен, не рекомендуется).
В качестве немного более грязной альтернативы вы можете переместить общий указатель (или его эквивалент) в c1_iface
и сделать функции не абстрактными, разыменовывая их.
Это не должно даже компилироваться ... или, по крайней мере, давать массу предупреждений. – fredrik
@fredrik Умм, почему? – Angew
@fredrik: На самом деле это совершенно верно. Это нехорошо, и он включает в себя заголовки C, но он абсолютно корректен и будет компилироваться без каких-либо ошибок или предупреждений. – Zeta