Pastx
Pastx

Reputation: 767

Polymorphism with abstract class (C++)

this is my code:

#include <cstdlib>
#include <vector>
#include <iostream> 
#include <cstring>  

using namespace std;
//abstract class
class GMatrix {
    string name;
    int nrows;
    int ncols;
public:
    GMatrix(const string & n, int nr, int nc);
     virtual GMatrix& add(const GMatrix&)= 0;
};

class RMatrix : public GMatrix {
    vector<int>numbers;
public:
    RMatrix(const string & n, int nr, int nc, vector<int> nums);
    RMatrix& add(const RMatrix&);
};

GMatrix::GMatrix(const string& n, int nr, int nc){
    name=n;
    nrows=nr;
    ncols=nc;
}

RMatrix::RMatrix(const string & n,int nr, int nc, vector<int> nums):GMatrix(n,nr,nc){
    numbers=numbers;   
}

RMatrix& RMatrix::add(const RMatrix& x){
    for(int i =0; i = numbers.size(); i++){
        numbers.at(i)+=x.numbers.at(i);
    }
}

int main(int argc, char** argv) {
    vector<int> n;
    for (int i = 0; i < 16 ; i++){
        n.push_back(i);
    }

    RMatrix a("a",4,4,n);
    return 0;
}

As you can see, my program consists of two classes, one (parent class) is abstract so methods here have no functionality and one children class. My problem is that this code canot be build. I try to create object a as RMatrix object but compiler shows this errors which i dont understand:

main.cpp:48:13: error: cannot declare variable ‘a’ to be of abstract type ‘RMatrix’
main.cpp:18:7: note:   because the following virtual functions are pure within ‘RMatrix’:
main.cpp:15:23: note:   virtual GMatrix& GMatrix::add(const GMatrix&)

Upvotes: 1

Views: 119

Answers (4)

4pie0
4pie0

Reputation: 29724

The method

RMatrix& RMatrix::add(const RMatrix&);

doesn't override

virtual GMatrix& GMatrix::add(const GMatrix&)= 0;

so code fails because GMatrix::add is pure virtual. You can add {} to solve the issue (by the way at the moment it looks like you don't need GMatrix::add at all...):

class GMatrix {
    string name;
    int nrows;
    int ncols;
public:
    GMatrix(const string & n, int nr, int nc);
     virtual GMatrix& add(const GMatrix&){}
};

class RMatrix : public GMatrix {
    vector<int>numbers;
public:
    RMatrix(const string & n, int nr, int nc, vector<int> nums);
    RMatrix& add(const RMatrix&);
};

http://ideone.com/SLObkC

Upvotes: 1

Eric Finn
Eric Finn

Reputation: 8985

The problem is that RMatrix's add member function does not match the signature of the pure virtual add function in GMatrix.

What you need is

GMatrix & RMatrix::add(const GMatrix &)

but what you have is

RMatrix & RMatrix::add(const RMatrix &)

The function you have does not match the signature conceptually (as in, this paragraph is about OOP in general, not just C++) because while all RMatrixs are GMatrixs, not all GMatrixs are RMatrixs. This means that if somebody does something like create a class FooMatrix that extends GMatrix, then creates instances of FooMatrix and RMatrix and uses GMatrix references to access them, they will not be able to use the RMatrix& RMatrix::add(const RMatrix&) method to add the two matrices, even though GMatrix specifies that the add method that concrete subclasses implement must be able to be called using any GMatrix.

Upvotes: 4

You are breaking the Liskov's substitution principle. Your derived type cannot be used in place of the base, since you can add any GMatrix to the base, but only RMatrix to the derived type.

The add member function in the derived type is not an override of the member function by the same name in the base type.

Upvotes: 3

yizzlez
yizzlez

Reputation: 8805

RMatrix is also an abstract class because you haven't implemented the

virtual GMatrix& add(const GMatrix&)= 0;

method. In RMatrix, this method is still pure virtual. This is why you cannot construct an RMatrix object.

Upvotes: 1

Related Questions