如何一般地写一个隐藏结构的属性? (C ++的设计/实现)

时间:2013-06-13 18:28:05

标签: c++ templates

假设我有以下模板。

template<typename T>
class MyClass
{
public:
    .............
private:
   T _data;
}

当我使用它时,T始终是一个结构(仅限数据)。例如,

struct ST1{
    int a;
    int b;
};
struct ST2{
    int a1;
    int b1;
    int c1;
}

对于MyClass的特定实例,例如MyClass<struct ST1> myinstance,我想访问myinstance.data.amyinstance.data.b。我能想到的一种通用方法是在MyClass中定义方法,如

void MyClass::write(T const &){ _data = T;}
T    MyClass::read(){return _data;}

但问题是,对于每次读写,我都需要创建一个结构实例,即使我只访问_data的一小部分。

由于

2 个答案:

答案 0 :(得分:1)

怎么样......

const T& MyClass::GetData() const { return _data; }
T& MyClass::GetData() { return _data; }

然后你就可以......

myClass.GetData().a = 17;

你也可以公开_data

答案 1 :(得分:1)

你要做的第一件事就是考虑公开_data。如果它只是数据,并且它没有活动,并且暴露其二进制布局不是问题,那么这是有效的。

如果您希望能够“挂机”访问_data(例如,使用互斥锁,或远程获取/设置某些信息),并且您可以访问C ++ 11 lambdas,则此模式可以是有用:

template<typename Lambda>
auto Data( Lambda&& closure )->decltype( closure(_data) ) {
  // do pre-processing
  auto retval = closure(_data);
  // do post-processing
  return retval;
}
template<typename Lambda>
auto Data( Lambda&& closure ) const->decltype( closure(_data) ) {
  // do pre-processing
  auto retval = closure(_data);
  // do post-processing
  return retval;
}

你会像这样使用:

int main() {
  MyClass<Foo> instance;
  int x = instance.Data( [&]( Foo const& foo ) {
    return foo.x;
  });
  instance.Data( [&]( Foo& foo ) {
    foo.y = 3;
  });
}

可让您操纵数据“内部”包裹MyClass的代码。

在C ++ 14 auto lambdas出现之前,这有点尴尬,因为你必须重复Foo的类型。

这种风格的好处是MyClass甚至不必存储Foo的实例!它可以按需生成Foo,然后从用户更改的内容中回读。