Question

I am pretty new to C++. Today, I am experiencing some issues in mixing nested classes and interfaces.

I wrote a small (useless) program that will be more effective at explaining my issue than long sentences:

#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;
}

Here, the program compiles fine if I remove the line virtual reference operator[](unsigned int pos) = 0; in the interface. However, I would like the array subscript operator to be part of the interface.

The error message thrown by G++ is invalid abstract return type for member function ‘virtual SomeInterface::reference SomeInterface::operator[](unsigned int)’.

I do understand why it fails. But I can't figure out any way to make something like this work. Can anybody explain why I am doing (or thinking) wrong?

Was it helpful?

Solution

You can not create objects of type SomeInterface::reference, since it is a pure abstract class, and that is what the compiler told you.

You need to return a reference (or a pointer) to such class. Like this :

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

but then :

  1. in derived classes, you shouldn't change the signature of the pure virtual methods. It should stay virtual SomeInterface::reference& operator[](unsigned int pos)
  2. you can not return reference to a temporary object

btw take care how you create objects of such classes. They do not have virtual destructors.

OTHER TIPS

Basically you can't return a reference to something that can never exist. However, you could use a pointer to an abstract class. That pointer will ultimately only be able to point to an instance of a derived class.

It is not clear exactly what you are trying to do. But you might look into Creation Patterns to find something close to what you need

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top