考虑以下代理类:
class VertexProxy
{
public:
VertexProxy(double* x, double* y, double* z)
: x_(x), y_(y), z_(z) {}
VertexProxy(const VertexProxy& rhs)
: x_(rhs.x_), y_(rhs.y_), z_(rhs.z_) {}
// Coordinate getters
double x() const {return *x_;}
double y() const {return *y_;}
double z() const {return *z_;}
// Coordinate setters
VertexProxy& x(double val) {*x_ = val; return *this;}
VertexProxy& y(double val) {*y_ = val; return *this;}
VertexProxy& z(double val) {*z_ = val; return *this;}
VertexProxy& operator=(const VertexProxy& rhs)
{
// Should it be this
x_ = rhs.x_; y_ = rhs.y_; z_ = rhs.z_;
// or this?
*x_ = *rhs.x_; *y_ = *rhs.y_; *z_ = *rhs.z_;
return *this;
}
private:
double* x_; double* y_; double* z_;
};
我需要能够重置代理,以便它拥有不同的坐标指针(类似于boost::shared_ptr.reset()
。此外,我希望能够将坐标值分配给来自不同代理的坐标值(即proxy1.assign(proxy2)
)。
我班上operator=
的含义应该是什么?复制rhs
的指针(浅拷贝)或rhs
的值?或者我应该operator=
私有并提供两个成员函数以避免operator=
的含糊不清?
修改
好的,这是一些背景信息。我正在围绕第三方GIS库(shapelib)编写一个包装器,它将顶点坐标(x,y,z,m)存储在单独的数组中(而不是结构数组)。我的代理类用于使这个数组结构看起来更像一个结构数组。它与自定义顶点迭代器类协同工作,使得处理顶点范围变得更加容易。
Shapelib处理内存管理。我的所有代理类都在顶点数据中显示不同的“视图”。当用户使用我的代理操纵顶点坐标时,它实际上操纵了shapelib形状对象中的顶点坐标。
答案 0 :(得分:3)
鉴于您的复制构造函数复制了指针,为了保持一致性,您的复制赋值运算符应该指定指针。
VertexProxy& operator=(const VertexProxy& rhs)
{
x_ = rhs.x_;
y_ = rhs.y_;
z_ = rhs.z_;
return *this;
}
如果这个(确实有问题的)代码会非常不一致:
VertexProxy test( const VertexProxy& other )
{
double tmp1, tmp2, tmp3;
VertexProxy p1( &tmp1, &tmp2, &tmp3 );
p1 = other;
return p1;
}
采取不同的行动:
VertexProxy test( const VertexProxy& other )
{
double tmp1, tmp2, tmp3; // unused
VertexProxy p1( other );
return p1;
}
答案 1 :(得分:2)
这很简单。您希望VertexProxy像指针或值一样工作吗?如果你更喜欢它的作用就像一个指针,那么复制指针,如果你更喜欢它像一个值,复制值。没有人可以告诉你,你的类是一个指针或一个值(特别是因为你似乎有一些不寻常的东西)。如果你想要更好的建议,我们需要知道什么是实际的双打和原因。
快速修改: 实际上对我来说,如果你做了解除引用,你会让它像一个引用或一个指针。但是,原始观点保持不变。
答案 2 :(得分:1)
std::bitset::reference
执行与VertexProxy
类似的角色,可以用作模型。
typedef std::bitset<8> Bitset;
Bitset bset1, bset2;
Bitset::reference r1(bset1[3]);
Bitset::reference r2(bset2[3]);
r1 = 1;
r2 = r1;
std::cout << "bset2 = " << bset2 << "\n";
上面的 r2 = r1
复制值。
答案 3 :(得分:0)
我想说这取决于对象的大小。
如果代理主题非常大,那么使用引用计数共享指针是可行的方法。只需在复制操作中复制共享指针。
如果不是那么大,那么深拷贝就更好了。每个人都不那么麻烦。