【问题标题】:How to use a C++ class with pure virtual function?如何使用具有纯虚函数的 C++ 类?
【发布时间】:2016-04-26 18:17:38
【问题描述】:

我得到了一个纯虚函数的类,如下所示:

类 IRecordingHour{
    上市:
        虚拟 int getData() const = 0;
} 

现在,我有另一个使用 IRecordingHour 类的类:

 类 ProcessRecordingHours { 
公开:
ProcessRecordingHours (IRecordingHour &);
受保护:
IRecordingHour &recordingHour;
}

有人告诉我,我不允许实现 IRecordingHour 类(具有纯虚函数的类)。

我的问题是:没有实现 IRecordingHour 类,我如何在 ProcessingRecordingHours 中使用它?也就是如何创建IRecordingHour的实例并将其传递给ProcessRecordingHours的构造函数?

【问题讨论】:

    标签: interface


    【解决方案1】:

    你应该创建一个IRecordingHour的子类并实现getData方法,比如

    class ARecordingHour : public IRecordingHour
    {
       public:
          int getData() const override //override is valid from C++11 
          {
             return 42;
          }
    }
    

    然后你可以这样做:

    ARecordingHour arh{};
    ProcessRecordingHours prh{arh}; //{}- Modern C++ initialization
    

    你可以在一本不错的C++编程书籍中找到类似的例子,比如The C++ Programming Language

    【讨论】:

      【解决方案2】:

      虽然你把它们等同起来,但你的两个问题实际上是完全不同的。

      如何在 ProcessingRecordingHours 中使用它?

      在不实现IRecordingHour 的子类的情况下实现ProcessingRecordingHours 没有特别的问题。你不需要做任何特别的事情。您只需避免依赖 IRecordingHour 未声明的任何内容,这与您应该做的没有什么不同。

      如何创建 IRecordingHour 的实例并将其传递给 ProcessRecordingHours 的构造函数?

      你不能。具有纯虚方法的类不能直接实例化。你的ProcessRecordingHours 可以与扩展IRecordingHour 的类一起使用,但是如果你不允许创建这样的类,那么你就不能使用依赖于IRecordingHourProcessRecordingHours 类的那些部分。

      但是,也许您误解了这个问题。你可能被禁止实现IRecordingHour::getData(),但不能实现一个用具体方法覆盖该方法的子类。这样的子类可以是可实例化的,并且可以与ProcessRecordingHours 结合使用。

      【讨论】:

      • 感谢您的回复。我可能像你说的那样误解了这个问题。以下是完整描述:
         实现 ProcessRecordingHours 类并使用 GoogleTest 和 GoogleMock 提供单元测试。您不需要实现 IRecordingHour 类。对其 getData() 函数的返回值施加的所有约束都可以依赖,不需要测试"
      【解决方案3】:

      我认为您的老师计划将 IRecordingHour 的实现注入 ProcessRecordingHours。

      此外,您不能使用该类,除非您为 IRecordingHour 生成一个存根,或者您自己使用一些虚拟返回值实现一个存根。

      /// <summary>
      /// in C# and interface can only contain virtual methods. so no need to say virtual.
      /// </summary>
      interface IRecordingHour
      {
          int getData();
      }
      
      class MockRecordingHour : IRecordingHour
      {
          public int getData()
          {
              //just return something. This will be enough to get ProcessRecordingHours to work
              return 100;
          }
      }
      
      /// <summary>
      /// this class expects a IRecordingHour.
      /// 
      /// how we get a IRecordingHour depends on who's implementing it. You, some 3rd party vendor or another developer who's using this class that you've written.
      /// 
      /// Oh wait. Since you're building ProcessRecordingHours, you need a IRecordingHour to get against. You can use a mocking tool or create one yourself that returns some dummy data
      /// </summary>
      class ProcessRecordingHours
      {
          private IRecordingHour _recording;
      
          public ProcessRecordingHours(IRecordingHour recording)
          {
              this._recording = recording; 
          }
      
          public void DoSomething() {
              Console.WriteLine("Recording Data: {0}", this._recording.getData());
          } 
      
      }
      

      【讨论】:

      • KMC,感谢您的回复。如何为 IRecordingHour 生成存根?另外,我的老师计划将 IRecordingHour 的实现注入到 ProcessingRecordingHours 类中是什么意思?请给一些代码好吗?
      • 既然你说“我被告知我不允许实施 IRecordingHour 课程”,我以为你是一名学生,你的老师给你这个任务作为你构建的小组项目的一部分出 ProcessRecordingHours 和其他人实现 IRecordingHour。继续阅读单元测试,就会出现模拟的概念。
      • 如果我做出了错误的假设,我深表歉意。当我上大学的时候,这是一个标准的练习。
      • 感谢 KMC,您的回答真的很有帮助。没必要道歉。是我的措辞让你有这样的假设。
      猜你喜欢
      • 2011-11-29
      • 1970-01-01
      • 1970-01-01
      • 2015-12-20
      • 2013-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多