【问题标题】:Mixing interfaces and nested classes in C++在 C++ 中混合接口和嵌套类
【发布时间】:2013-10-15 21:01:10
【问题描述】:

我对 C++ 很陌生。今天,我在混合嵌套类和接口时遇到了一些问题。

我写了一个小(无用)程序,它比长句更能有效地解释我的问题:

#include <iostream>
#include <vector>

class SomeInterface {
  public:
    virtual int SomeMethod() = 0;

    class reference {
      public:
        virtual operator int() const = 0;
        virtual reference& operator=(int x) = 0;
    };

    virtual reference operator[](unsigned int pos) = 0;
};

class A : public SomeInterface {
  public:
    A(unsigned int size) { vec_.resize(size, 0); }
    int SomeMethod() { return 1; }

    class reference : public SomeInterface::reference {
      public:
        reference(std::vector<int>::reference ref) : ref_(ref) { }
        operator int() const { return (int) this->ref_; }
        reference& operator=(int x) { this->ref_ = x; return *this; }
      private:
        std::vector<int>::reference ref_;
    };

    reference operator[](unsigned int pos) {
      return reference(this->vec_[pos]);
    };

  private:
    std::vector<int> vec_;
};

int main() {
  A a(10);
  a[5] = 42;
  std::cerr << a[5] << std::endl;
  return 0;
}

在这里,如果我删除界面中的virtual reference operator[](unsigned int pos) = 0; 行,程序编译正常。但是,我希望数组下标运算符成为接口的一部分。

G++抛出的错误信息是invalid abstract return type for member function ‘virtual SomeInterface::reference SomeInterface::operator[](unsigned int)’

我明白它为什么会失败。但我想不出任何办法来做这样的事情。谁能解释我为什么做错(或思考)错了?

【问题讨论】:

  • 如果你想重写一个虚函数,返回类型必须是协变的。您可以在此处通过返回对reference 的引用或指针来执行此操作,但这可能会破坏reference 类的要点。

标签: c++ interface nested-class


【解决方案1】:

你不能创建SomeInterface::reference类型的对象,因为它是一个纯抽象类,编译器就是这么告诉你的。

您需要返回对此类的引用(或指针)。像这样:

virtual reference& operator[](unsigned int pos) = 0;

然后:

  1. 在派生类中,不应更改纯虚方法的签名。它应该保持virtual SomeInterface::reference&amp; operator[](unsigned int pos)
  2. 您不能返回对临时对象的引用

顺便说一句,注意如何创建此类类的对象。它们没有虚拟析构函数。

【讨论】:

  • 而且,正如评论所指出的,这将破坏reference 类的要点(即返回一个临时对象)。例如,只是为了遵守vector::reference 标准。现在,我想我会放弃为此创建一个界面...感谢您的解释!
【解决方案2】:

基本上,您不能返回对永远不存在的事物的引用。但是,您可以使用指向抽象类的指针。该指针最终只能指向派生类的实例。

目前尚不清楚您要做什么。但是您可能会研究创建模式以找到接近您需要的东西

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-26
    • 2019-09-26
    • 1970-01-01
    • 1970-01-01
    • 2011-08-01
    • 1970-01-01
    • 2012-09-02
    • 1970-01-01
    相关资源
    最近更新 更多