Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pure virtual functions with arguments of the same class

Tags:

c++

I'd appreciate if anyone could enlighten me what is going on here: Say I declare the following

class Base {
public:
    virtual void member(Base b) = 0;
};

which give the following compiler error:

pvf.cpp:3:18: error: cannot declare parameter ‘b’ to be of abstract type ‘Base’
     virtual void member(Base b) = 0;
              ^
pvf.cpp:1:7: note:   because the following virtual functions are pure within ‘Base’:
     class Base {
   ^
pvf.cpp:3:18: note:     virtual void Base::member(Base)
     virtual void member(Base b) = 0;

However, if I pass by reference, it compiles without problems:

class Base {
public:
    virtual void member(Base& b) = 0;
};

Furthermore, I'd like to implement member() in the derived class as

class Base {
public:
virtual void member(Base& b) = 0;
};

class Derived : public Base {
public:
    void member(Derived& d) {};
};

int main() {
    Derived d;
}

However, (obviously?) I get

pvf.cpp: In function ‘int main()’:
pvf.cpp:12:14: error: cannot declare variable ‘d’ to be of abstract type ‘Derived’
    Derived d;
    ^
pvf.cpp:6:8: note:   because the following virtual functions are pure within ‘Derived’:
    class Derived : public Base {
    ^
pvf.cpp:3:15: note:     virtual void Base::member(Base&)
    virtual void member(Base& b) = 0;
like image 950
user32849 Avatar asked Sep 26 '22 16:09

user32849


1 Answers

Your first function

virtual void member(Base b) = 0;

takes a parameter of class Base by value which requires an instance of Base to be passed to it. But as Base is an abstract class (because it contains a pure virtual function) it cannot be instantiated and therefore you cannot create an instance of Base to pass to it! That is the reason for your first error.

In your second case, in your derived class you declare a function

void member(Derived& d) {};

which you may think overrides the base class virtual function

virtual void member(Base& b) = 0;

but it does not (it in fact, hides it - see Why does a virtual function get hidden? for an explanation of this), and so Derived remains abstract class because you have not provided an implementation of the pure virtual function in the base class. For this reason Derived also cannot be instantiated. Derived classes that fail to provide an implementation for a base class pure virtual function will remain abstract just like the base class.

like image 75
mathematician1975 Avatar answered Nov 15 '22 09:11

mathematician1975