如果基类被公共继承,基类的公共静态函数是否会成为派生类的成员函数?

时间:2019-02-05 22:24:09

标签: c++ templates inheritance compiler-errors singleton

我正在尝试运行以下代码,但出现错误。

#include <iostream>
template <typename T>
class Base {
  public :
    static T& Get() {
      static T t;
      return t;
    }
};    
class Derived : public Base<Derived> {
  private :
    Derived() {}
    // friend Base<Derived>;  //un-commenting this will make code work.
};                            

int main() {
  Derived& d = Derived::Get();
  return 0;
}
  

错误:

     
    

prog.cpp:实例化为“静态T&Base :: Get()[with T = Derived]”:
    prog.cpp:18:24:从此处开始
    prog.cpp:7:14:错误:“ Derived :: Derived()”在此上下文中是私有的
    静态T t;
            ^
    prog.cpp:14:4:注意:在此声明为私有
    Derived(){}
    ^ ~~~~~~

  

我有以下问题

  1. Derived是从类Base公开派生的,不是也使Get()成为Derived的成员函数吗?
  2. 如果[1]为真,并且Get()成为Derived的成员函数,则 为什么它无法调用Derived的私有构造函数。
  3. 假设我们有多个要作为Singleton实现的类, 有一种方法,我们可以使用类似于 上面的例子? (其他问题)

我了解:

  • 我们可以通过使base为derived的朋友来使上面的代码起作用 行到代码。
  • 我们可以将Get()设置为“非静态虚拟函数”并在 派生的类。

我不是在寻找上述解决方案。不过,请让我知道这是否是实现这种设计的唯一可行解决方案。

2 个答案:

答案 0 :(得分:2)

  

Derived类是从Base类公开派生的,不是也使Get()成为Derived的成员函数吗?

从某种意义上说,查找Derived::Get()可以工作,但是它调用的功能与您编写Base<Derived>::Get()时完全相同。

  

如果[1]为true,并且Get()成为Derived的成员函数,那么为什么它不能调用Derived的私有构造函数。

因为不同的类无法通过名称访问私有成员。这就是私有的目的。 Derived无法访问Base的私人成员的相同原因。

  

假设我们有多个类要实现为Singleton,是否可以使用与上述示例类似的模板来实现? (其他问题)

这不是您的示例在做什么吗?

  

我们可以通过使派生代码的朋友成为该代码的基础来使上述代码起作用。

正确。

  

我们可以将Get()设置为“非静态虚拟函数”,并在派生类中进行覆盖。

我不这么认为。没有对象就无法调用该虚函数。您需要在调用Derived之前创建Get的实例,但是应该使用Get创建我们的对象。

  

不过,请告诉我,这是否是实现这种设计的唯一可行解决方案。

我可能会去做朋友。简单,简洁,随心所欲。还有其他解决方案,例如在基础中具有受保护的类型,并定义一个接收该受保护的类型的公共构造函数,但这很容易泄漏,我不建议这样做。

答案 1 :(得分:2)

  
      
  1. Derived类是从Base类公开派生的,不是也使Get()成为Derived的成员函数吗?
  2.   

不。 base的成员函数(静态和非静态)是base的成员函数,而不是派生类的成员函数。但是,调用成员函数时会查询base的成员函数(取决于可见性)。