c++ - 在 C++ 中,是否可以将 CRTP 与私有(private)基一起使用?

标签 c++ crtp downcast static-cast private-inheritance

在 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() 在子类中是私有(private)的怎么办?如果子类从 NameMethods 私有(private)继承,则向下转换将无法编译(不可访问的基类)。我可以用 reinterpret_cast 替换它,一个简单的示例会起作用,但如果存在任何多重继承,则 reinterpret_cast 不会做正确的事情,这在一般情况下可能存在。

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

谢谢!

编辑:我应该添加一点背景。我正在尝试以一种尽可能使用协议(protocol)而不是抽象父类(super class)的风格来编写。如果我用一个公共(public)的 get_name() 和一个 protected print_name() 创建一个抽象父类(super class),我可以很容易地让一切正常工作。问题是我不想要抽象父类(super class)。它会有几个我希望不相关的子类(因为我最终想使用 mixin 或 MI 组合它们)。

我的想法是,我将编写一个具体类,并在该类或父类(super class)中的某处实现 get_name()。该具体类需要一组实用函数,但这些实用函数不应该是接口(interface)的一部分。

最佳答案

是的,你可以。 只要让你的 CRTP 基类成为你的类的 friend ,沮丧就会再次起作用:

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

关于c++ - 在 C++ 中,是否可以将 CRTP 与私有(private)基一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54702397/

相关文章:

c++ - TVirtualStringGrid CopyToClipboard 问题 Embarcadero Seattle C++

c++ - 具有静态存储持续时间的常量初始化变量的初始化顺序

c++ - CRTP 中未实现的派生函数

c++ - 我可以使用对派生类实例的基类引用来初始化派生类引用吗?

c++ - 在映射 C++ 中存储对象引用

c++ - 执行简单的 boost 线程程序时出错

c++ - 应用于模板类的 CRTP

c++ - 类静态变量初始化的规则是什么?

java - 向上转换为对象的 ArrayList 然后向下转换为自定义 ArrayList 的成本

swift - 从 [Any] 获取枚举原始值而不向下转换