c++ - 在 C++ 中,是否可以将 CRTP 与私有基础一起使用?
问题描述
在 C++ 中,我有许多与继承无关的类,它们定义了一个方法std::string get_name() const
。
许多类需要几个实用函数,它们是根据 get_name() 实现的。我希望实现 get_name() 的类也能获得这些实用函数。举一个愚蠢的例子,假设对于每个有 get_name 的类,我都想拥有void print_name() const { std::cout << get_name() << std::endl; }
. 不过,有一些这样的功能,我不想在每个需要它们的类中重复它们。
听起来像是 CRTP 的工作:
template <class T>
class NameMethods {
public:
void print_name() const {
std::cout << static_cast<const T&>(*this).get_name() << std::endl;
}
};
效果很好。
这是皱纹 - 如果我希望 print_name() 在子类中是私有的怎么办?如果子类从 NameMethods 私有继承,则向下转换将不会编译(不可访问的基础)。我可以用 reinterpret_cast 替换它,一个简单的例子可以工作,但是如果有任何多重继承,reinterpret_cast 就不会做正确的事情,这在一般情况下可能存在。
有没有简单的方法来做这种事情?
谢谢!
编辑:我应该添加一点背景。我正在尝试以尽可能使用协议而不是抽象超类的风格编写。如果我使用公共 get_name() 和受保护的 print_name() 创建一个抽象超类,我可以轻松地让一切正常工作。问题是我不想要一个抽象超类。它会有几个我希望不相关的子类(因为我最终想使用 mixins 或 MI 组合它们)。
我的想法是我将组成一个具体的类,并且在该类或超类中的某个地方,某些东西将实现 get_name()。该具体类将需要一组实用函数,但这些实用函数不应该是接口的一部分。
解决方案
是的你可以。只需让您的 CRTP 基类成为您班级的朋友,向下转型将再次起作用:
template <class T>
class NameMethods {
public:
void print_name() const {
std::cout << static_cast<const T&>(*this).get_name() << std::endl;
}
};
class MyClass: private NameMethods<MyClass>
{
public:
std::string get_name() const { return "MyClass";}
void get_info() const
{
print_name();
}
private:
friend class NameMethods<MyClass>;
};
int main()
{
MyClass c;
c.get_info();
return 0;
}
推荐阅读
- python - 在类中使用 namedtuple
- react-native - 无法在 Expo Camera recordAsync 上设置“质量”
- mobile-robot-toolkit - .simplemap 到 octomap/点云和地面实况机器人位姿转换
- android - 保证金不适用于视图 API 22
- vba - 使用 Word 宏/VBA 将表格从一个 Word 文档复制到另一个 Word 文档
- c# - 如何将 API 的 Body 参数传入 C#
- python - 检索列表中的字典项?Python
- sql - 使用 SQL Server 导入向导将 CSV 上传到表时出现日期错误
- python - 数据框值比较
- python - python完全限定域名