Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/118.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何编写隐藏结构&x27;一般的属性是什么?(C+;+;的设计/实现)_C++_Templates - Fatal编程技术网

C++ 如何编写隐藏结构&x27;一般的属性是什么?(C+;+;的设计/实现)

C++ 如何编写隐藏结构&x27;一般的属性是什么?(C+;+;的设计/实现),c++,templates,C++,Templates,假设我有以下模板 template<typename T> class MyClass { public: ............. private: T _data; } 对于MyClass的特定实例,例如,MyClass myinstance,我想访问myinstance.data.a或myinstance.data.b。我能想到的一种通用方法是在MyClass中定义方法,如 void MyClass::write(T const &){ _data =

假设我有以下模板

template<typename T>
class MyClass
{
public:
    .............
private:
   T _data;
}
对于MyClass的特定实例,例如,
MyClass myinstance
,我想访问
myinstance.data.a
myinstance.data.b
。我能想到的一种通用方法是在MyClass中定义方法,如

void MyClass::write(T const &){ _data = T;}
T    MyClass::read(){return _data;}
但问题是,对于每次读写,我都需要创建一个结构实例,即使我只访问一小部分
\u数据

谢谢

那么

const T& MyClass::GetData() const { return _data; }
T& MyClass::GetData() { return _data; }
然后你就可以做

myClass.GetData().a = 17;

您也可以将
\u数据
公开。

您应该做的第一件事是考虑将
\u数据
公开。如果它只是数据,并且不处于活动状态,并且暴露其二进制布局也不是问题,那么这就行了

如果您希望能够“bookend”访问
\u数据
(例如,使用互斥锁,或远程获取/设置某些信息),并且可以访问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;
}
模板
自动数据(Lambda和&closure)->decltype(闭包(_数据)){
//做预处理
自动检索=关闭(_数据);
//做后处理
返回返回;
}
模板
自动数据(Lambda&闭包)常量->decltype(闭包(_数据)){
//做预处理
自动检索=关闭(_数据);
//做后处理
返回返回;
}
您可以这样使用:

int main() {
  MyClass<Foo> instance;
  int x = instance.Data( [&]( Foo const& foo ) {
    return foo.x;
  });
  instance.Data( [&]( Foo& foo ) {
    foo.y = 3;
  });
}
intmain(){
MyClass实例;
int x=instance.Data([&](Foo const&Foo){
返回foo.x;
});
instance.Data([&](Foo&Foo){
foo.y=3;
});
}
它允许您在
MyClass
的包装代码中“内部”操作数据

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


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

您希望
\u数据
隐藏并显示实现细节,还是希望
MyClass
的用户访问它?在后一种情况下,只需公开。感觉就像是你在制造问题。返回对
\u data
的引用的getter方法就可以了,尽管它破坏了封装,但你的写和读也是如此。比我的更糟糕。很简单。谢谢,我反对这种模式,因为如果你这样做,为什么不直接公开数据呢?上述方法已经公开了
\u data
的二进制布局,用户更改
\u data
后,您无法对其进行任何后处理。。。
int main() {
  MyClass<Foo> instance;
  int x = instance.Data( [&]( Foo const& foo ) {
    return foo.x;
  });
  instance.Data( [&]( Foo& foo ) {
    foo.y = 3;
  });
}