用于访问容器<T>数据成员的正确 API
Proper API for access data members of container<T>
我有以下类:
class Document
{
public:
Document():
// default values for members,
// ...
m_dirty{false}{}
// Accessor functions
template<class OutputStream>
Document& save(OutputStream stream)
{
// Write stuff to `stream`
// ...
m_dirty = false;
return *this;
}
bool dirty() const { return m_dirty; }
private:
Size2d m_canvas_size;
LayerStack m_layers;
LayerIndex m_current_layer;
std::vector<Palette> m_palettes;
PaletteIndex m_current_palette;
ColorIndex m_current_color;
std::vector<std::string> m_palette_names;
std::vector<std::string> m_layer_names;
bool m_dirty;
};
类是否应该具有用于直接修改m_palette元素的公共成员函数,如
Document& color(PaletteIndex, ColorIndex, Color)
,还是更";"正确";,只允许通过一对API的访问整个向量
std::vector<Palette> const& palettes();
Document& palettes(std::vector<Palette>&&);
第一种选择会更高效,因为它不需要创建数据成员的临时副本,但这种设计的一致使用会使接口变得臃肿。这将需要";深";类中每个容器的getter和setter。
注意脏标志。因此,以下内容将打破抽象:
std::vector<Palette>& palettes();
您可能有代理"传播";调色板修改中的脏标志,类似于:
template <typename T>
class DirtyProxy
{
T& data;
bool& dirty;
public:
DirtyProxy(T& data, bool& dirty) : data(data), dirty(dirty) {}
~DirtyProxy() { dirty = true;}
DirtyProxy(const DirtyProxy&) = delete;
T* operator ->() { return data; }
};
然后
DirtyProxy<Palette> palette(std::size_t i) { return {m_palettes.at(i), dirty}; }
我认为解决它最稳健的方法是使用回调。代理的一个问题是,它无法处理客户端代码抛出异常的情况(假设有强大的异常保证(。测试用例:
try
{
auto property_proxy = obj.getProperty();
// an exception is thrown here...
property_proxy->val = x; // Never updated
}
catch(...)
{}
assert(!obj.dirty());
将失败,因为dtor总是设置脏标志。然而,使用回调
class Foo
{
public:
template<class F>
Foo& modifyInSitu(F&& f)
{
f(x);
m_dirty = true;
return *this
}
};
将仅在f(x)
未抛出时更新m_dirty
。
相关文章:
- 用于访问容器<T>数据成员的正确 API
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 数据成员SFINAE的C++17测试:gcc vs clang
- 派生类是否可以在抽象工厂设计模式中具有数据成员
- 如何在c++中定义以struct为数据成员的类中的构造函数
- 静态数据成员模板专用化的实例化点在哪里
- int数据类型的指针指向的是什么,如果是一个类的私有数据成员,我们创建了该类的两个对象?
- 使用指针访问数组中的对象数据成员
- 友元函数无法访问私有数据成员 (c++)
- 我可以在 C++ 中将数据成员/变量从其定义之外添加到结构中吗?
- 为什么将一个结构的引用设置为等于另一个结构只会更改一个数据成员?
- 将私有数据成员添加到野牛生成的类中
- 输入数据成员未按要求工作
- 二维矢量数据成员
- 在类 A 中创建类型为 B 类的向量 - 访问数据 [C++] [成员在两个类中都是私有的]
- 调用在 HXX 文件中声明的静态数据成员
- 是否可以根据其数据成员的类型确定类型的大小
- 访问数据成员(本身是对象)的数据成员,就好像它们是类成员一样
- 使公共数据成员在C++中无法访问
- 临时数据成员的寿命延长和 API 设计