在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替换它,一个微不足道的示例会起作用,但是如果有任何多个继承,则retinterpret_cast不会做正确的事情。

有一种简单的方法可以做这种事情吗?

谢谢!

编辑:我应该添加一些背景。我正在尝试以一种在可能的情况下使用协议而不是抽象超类的样式编写。如果我使用public 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;
}

请参阅实时示例:https://godbolt.org/z/5oqvsq

最新更新