奇怪的重复模板模式 - 继承和朋友
Curiously Recurring Template Pattern -- Inheritance and friends
into
我正在尝试使用奇怪的重复模板模式,以使其在HDF5组中可存储。但是我有两个问题:
- 如何使会员实施私有?
- 如何将CRTP与名称空间使用?
我想要的
(遵循代码)hdf5::Group
代表HDF5组,并且可以存储数据集。hdf5::Storable
是CRTP模板类。函数hdf5::store
应采用一个组和一个可存储的对象,并调用对象的实现。所有这些都应在命名空间hdf5
内保持清洁。
A
实现了存储。它生活在hdf5
名称空间(例如全局或其他名称空间)之外。实现方法A::store
应该是私有的,以确保每个人都使用hdf5::store
。
我拥有的
所讨论的部分有评论指出问题。
#include <string>
#include <iostream>
namespace hdf5 {
/// A group can contain other groups, and datasets.
class Group {
public:
/// Create a group under a parent group.
Group(Group* parent, const std::string &name)
: parent_(parent), name_(name)
{
std::cout << "Creating group "" << name << """;
if (parent != nullptr)
std::cout << " under "" << parent->name_ << """;
std::cout << "." << std::endl;
};
/// Create a root group.
Group() : Group(nullptr, "root") { }
/// Create a dataset inside.
void create_dataset(const std::string &name)
{
std::cout << "Creating dataset "" << name << """
<< " under "" << name_ << ""." << std::endl;
}
private:
Group *parent_;
std::string name_;
};
/** Abstraction of a storable class.
*
* Curiously recurring template pattern.
* Makes it possible to write
*
* store(grp, obj);
*
*/
template<class Derived>
class Storable {
friend void hdf5::store(hdf5::Group &grp, const Derived &obj) {
obj.store(grp);
}
};
} // namespace hdft
/// Some data class that should be storable.
class A : private hdf5::Storable<A> {
public:
A(const std::string &name) : name_(name) { }
/*
* Why can't I make it private? `store` should be friend.
*
* test.cc: In instantiation of ‘void hdf5::store(hdf5::Group&, const A&)’:
* test.cc:104:19: required from here
* test.cc:72:10: error: ‘void A::store(hdf5::Group&) const’ is private
* void store(hdf5::Group &grp) const {
* ^
* test.cc:45:9: error: within this context
* obj.store(grp);
* ^
*/
// private:
public:
/// Implementation of the storage
void store(hdf5::Group &grp) const {
grp.create_dataset(name_);
}
private:
std::string name_;
};
/// Demonstration.
int main(void) {
hdf5::Group root,
grpa(&root, std::string("group_a")),
grpb(&root, std::string("group_b"));
A a1(std::string("A1")), a2(std::string("A2"));
/*
* This is what I want, but it doesn't compile:
*
* test.cc: In function ‘int main()’:
* test.cc:96:5: error: ‘store’ is not a member of ‘hdf5’
* hdf5::store(root, a1);
* ^
*/
// hdf5::store(root, a1);
// hdf5::store(root, a2);
// hdf5::store(grpa, a1);
// hdf5::store(grpb, a2);
/*
* This OTOH compiles and runs.
*/
store(root, a1);
store(root, a2);
store(grpa, a1);
store(grpb, a2);
}
预期输出
Creating group "root".
Creating group "group_a" under "root".
Creating group "group_b" under "root".
Creating dataset "A1" under "root".
Creating dataset "A2" under "root".
Creating dataset "A1" under "group_a".
Creating dataset "A2" under "group_b".
以下更改似乎有效:https://ideone.com/crulkb
namespace hdf5 {
// Previous stuff
template <class Derived> void store(hdf5::Group &grp, const Derived&obj);
template<class Derived>
class Storable {
static void store(hdf5::Group &grp, const Derived&obj)
{
obj.store(grp);
}
friend void hdf5::store<>(hdf5::Group &grp, const Derived&obj);
};
template <class Derived>
void store(hdf5::Group &grp, const Derived&obj) {
Storable<Derived>::store(grp, obj);
}
} // namespace hdf5
/// Some data class that should be storable.
class A : private hdf5::Storable<A> {
friend class hdf5::Storable<A>;
private:
/// Implementation of the storage
void store(hdf5::Group &grp) const {
grp.create_dataset(name_);
}
private:
std::string name_;
};
相关文章:
- 为什么在保护模式下继承升级不起作用
- 具有多个继承共享一个资源的对象 - 寻找良好的设计模式
- 工厂方法模式使用继承而抽象工厂模式使用组合如何
- 在我的情况下,多重继承是一种好的设计模式吗?
- 具有多个继承的工厂模式
- 设计模式:我应该在这里使用继承吗?
- 从虚拟公共模式下的模板类继承的类的原型
- 具有静态属性(服务定位器模式)的模板继承
- 奇怪的重复模板模式 - 继承和朋友
- 在发布模式下禁用从C++中的基类继承
- 装饰设计模式与继承
- 依赖注入/继承设计模式的构造函数参数太多
- 设计模式:继承和封装继承
- 观察者模式和继承:未调用正确的函数
- 奇怪重复的模板模式多态拷贝(C++)中的继承
- 这种编译时确定继承的模式有名字吗
- 带有继承的C++Builder模式
- 不同的类模式:条件构造函数/方法与继承
- C++继承模式
- 具有继承的桥接设计模式,其中抽象基类具有成员数据