具有抽象类的多态性(C++)

Polymorphism with abstract class (C++)

本文关键字:C++ 多态性 抽象类      更新时间:2023-10-16

这是我的代码:

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

如您所见,我的程序由两个类组成,一个(父类(是抽象的,因此这里的方法没有功能,还有一个子类。我的问题是无法构建此代码。我尝试将对象 a 创建为 RMatrix 对象,但编译器显示我不明白的错误:

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&)

问题是RMatrixadd成员函数与GMatrix中纯虚add函数的签名不匹配。

你需要的是

GMatrix & RMatrix::add(const GMatrix &)

但你拥有的是

RMatrix & RMatrix::add(const RMatrix &)

您拥有的函数在概念上与签名不匹配(例如,本段是关于 OOP 的一般内容,而不仅仅是 C++(,因为虽然所有RMatrix都是 GMatrix s,但并非所有GMatrix都是 RMatrix s。这意味着,如果有人做一些事情,比如创建一个扩展GMatrix的类FooMatrix,然后创建FooMatrixRMatrix的实例,并使用GMatrix引用来访问它们,他们将无法使用RMatrix& RMatrix::add(const RMatrix&)方法添加两个矩阵,即使GMatrix指定具体子类实现的add方法必须能够使用任何GMatrix调用。

你正在打破利斯科夫的替代原则。派生类型不能代替基,因为可以向基中添加任何GMatrix,但只能RMatrix到派生类型。

派生类型中的add成员函数不是基类型中同名的成员函数的重写

RMatrix也是一个

抽象类,因为你还没有实现

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

方法。在RMatrix,这种方法仍然是纯虚拟的。这就是无法构造RMatrix对象的原因。

方法

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

不覆盖

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

所以代码失败GMatrix::add因为它是纯虚拟的。您可以添加{}来解决问题(顺便说一下,目前看起来您根本不需要GMatrix::add...

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