如何创建一个可以从其基类实例中更改所有变量的派生类?我理解我可以声明基类变量是静态的,但是当我这样做时,我无法使用函数初始化它们,这使得代码非常消息并且难以编辑。
这是一个示例类;为什么c2不能在theC1类中编辑x。如果它引用的是不是C1的c1类,那么引用的是什么?
#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;
}
答案 0 :(得分:2)
您正在使用引用来调用c1
的复制构造函数,而不是保存对c1
对象的引用。你想要这样的东西:
class c2 : public c1
{
public:
c2( c1& ref )
: c1_ptr(&ref) {}
void setx()
{
c1_ptr->x = 5;
this->x = 5;
}
private:
c1 * c1_ptr;
};
但是,这需要c1
的默认构造函数。如果您根本不需要任何构造,则可能需要使用代理类:
class c1_proxy
{
public:
c1_proxy( c1& ref )
: x(ref.x), c1_ptr(&ref) {}
void setx()
{
c1_ptr->x = 5;
}
int & x;
private:
c1 * c1_ptr;
};
但是,我认为这是反模式。请注意,您必须手动更新所有值。
答案 1 :(得分:1)
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
封装起来,而不是将其公开,并且必须使用上面代码中的参考技巧。
<强>更新强>
更大规模实施此方法的一种方法可能是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
并使函数非抽象,解除引用。