在C ++中,是否可以将CRTP与私有库一起使用?

问题描述 投票:2回答:1

在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私下继承,那么downcast将不会编译(不可访问的base)。我可以用reinterpret_cast替换它,一个简单的例子可以工作,但如果有任何多重继承,reinterpret_cast将不会做正确的事情,在一般情况下可能存在。

有没有一种简单的方法来做这种事情?

谢谢!

编辑:我应该添加一些背景。我试图用尽可能使用协议的样式编写,而不是抽象超类。如果我使用公共get_name()和受保护的print_name()创建一个抽象超类,我可以很容易地使一切工作。问题是我不想要一个抽象的超类。它会有几个我想与之无关的子类(因为我最终想用mixins或MI来组合它们)。

我的想法是,我将编写一个具体的类,在该类或超类中的某个地方,某些东西将实现get_name()。该具体类将需要一组实用程序函数,但这些实用程序函数不应该是接口的一部分。

c++ crtp downcast static-cast private-inheritance
1个回答
1
投票

是的你可以。只需让您的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

© www.soinside.com 2019 - 2024. All rights reserved.