Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inheritance without pointers

Suppose that I have a class with a single abstract virtual function like this:

class MyClass{
  public:
    virtual void MyFunc() = 0;
};

And I have no other functions, and no data members. I can also guarantee that all class which inherit from this do not have any data members and have no other functions except an implementation of MyFunc.

The biggest reason (at least in my mind) for forcing you to have a pointer to an abstract object is the size of the implementation is unknown....So is there a way to instead of having a pointer to this class just giving an instance (or pseudo instance) of the class. Take this for example:

void AFunction(MyFunc inst){  //Note the lack of pointer
  inst.MyFunc();  //This should call the implementation
}

So is this even possible or am I just a wishful thinker?

like image 413
DarthRubik Avatar asked May 11 '16 01:05

DarthRubik


3 Answers

You must pass either a pointer or a reference. You cannot pass by value, because that, by definition, involves making a copy of the value; and, by definition again, you can't copy an instance of an abstract class. C++ does not work this way.

So, take your pick, either:

void AFunction(MyFunc *inst){
  inst->MyFunc();
}

or

void AFunction(MyFunc &inst){
  inst.MyFunc();
}

Those are your options. Whether the subclasses have anything else, besides the virtual method implementation, or whether the abstract class has anything else, besides the virtual method, is irrelevant. The answer does not change.

like image 165
Sam Varshavchik Avatar answered Oct 27 '22 09:10

Sam Varshavchik


It's not possible (without references or pointers).

class Interface {
  public:
    virtual void F() = 0;
};

class Implementation: public Interface {
  public:
    void F() {}
};

void SomeFunction(Interface x) {}

int main() {
  Implementation impl;
  SomeFunction(impl);
}

This is basically what you are suggesting. And if you were to compile this:

blah.cc:11:29: error: parameter type 'Interface' is an abstract class
void SomeFunction(Interface x) {}
                            ^

You could use references, but that's basically just pointers with a different syntax.

void SomeFunction(Interface & x) {}

int main() {
  Implementation impl;
  SomeFunction(impl);
}
like image 27
Bill Lynch Avatar answered Oct 27 '22 09:10

Bill Lynch


You could use std::function. You can pass it by-value without pointers but it acts like an interface for a function:

void AFunction(std::function<void()> myfunc){
    myfunc();  //This will call the implementation
}

You could create this "interface" using a lambda:

MyClass mc;
auto myfunc = [mc]{mc.MyFunc();};
AFunction(myfunc);

Internally, std::function uses type erasure.

You could create your own wrapper that can be passed by value but you are probably going to need to use some sort of pointer internally.

like image 32
Chris Drew Avatar answered Oct 27 '22 09:10

Chris Drew