C++ 中的虚拟类和继承

Virtual class and inheritance in c++

本文关键字:继承 虚拟 C++      更新时间:2023-10-16

我正在使用c ++开发一个新项目:

文件 A.cpp

#ifndef A_hpp
#define A_hpp
class A{
public:
    A(int at, int bt);
    ~A();
    virtual double b()=0;
    virtual double c()=0;
    virtual double g()=0;
private:
    int at;
    int bt;
};
#endif /* A_hpp */

文件 A.cpp

#include "A.hpp"
A::A(int at, int bt){
    this->at=at;
    this->bt=bt;
}
A::~A(){
    //no code
}

文件 B.hpp

#ifndef B_hpp
#define B_hpp
#include "A.hpp"
class B:public A{
public:
    B(int at, int bt, double val);
    ~B();
private:
    double *elems;
};
#endif /* B_hpp */

文件 B.cpp

#include "B.hpp"
#include "A.hpp"
B::B(int at, int bt, double val):A(at, bt){
    elems=new double[at*bt];
    for(int i=0;i<at*bt;i++)
        *(elems+i)=val;
}
B::~B(){
    delete []elems;
}
double A::c(){
        return *elem;
    }
double A::b(){
        return (*elem)-*(elem+1);
    }

double A::g(){
        return (*elem)*(*elem)*(*elem);
    }

当我在类 B 中实现这些虚函数 b((、c(( et g(( 时,我收到一个错误,使用未声明的标识符"elem">

问题是您错误地实现了基类虚拟函数的覆盖。

您的代码实际上正在做的是实现A中的纯虚函数,同时尝试使用来自B的类成员变量

给定基类:

class A
{
public:
    A(int at, int bt);
    ~A();
    virtual double b()=0;
    virtual double c()=0;
    virtual double g()=0;
private:
    int at;
    int bt;
};

您的孩子班级应该是:

class B:public A
{
public:
    B(int at, int bt, double val);
    ~B();
    virtual double b();
    virtual double c();
    virtual double g();
private:
    double *elem;
};

通过实现这样的B

B::B(int at, int bt, double val):A(at, bt)
{
    elem=new double[at*bt];
    for(int i=0;i<at*bt;i++)
    {
        *(elem+i)=val;
    }
}
double B::a()
{
    return *elem;
}
B::~B()
{
    delete []elem;
}
double B::b()
{
    return (*elem)-*(elem+1);
}
double B::g()
{
    return (*elem)*(*elem)*(*elem);
}

有一个错别字。将elem更改为elems

要实现虚拟继承,您必须在类B标头中添加方法:

virtual double b();
virtual double c();
virtual double g();

在实现中,更改命名空间A B在.cpp中:

double B::c(){
        return *elems;
    }
double B::b(){
        return (*elems)-*(elems+1);
    }
double B::g(){
        return (*elems)*(*elems)*(*elems);
    }
我认为

您将实现放置在特定B.cpp文件中误解为"在类 B 中实现某些内容"。如果你写double A::c(){ ...,你不会在类B中实现c,而是在类A中实现c,不管你在哪个文件中编写这个实现。而类A不知道elems,它是B的成员,是什么解释了Use of undeclared identifier 'elem'的错误消息。

改为编写double B::c(){ ...,并在类B的定义中声明double c()。(当然其他功能也是如此(

elems 是类 B 的成员,该类派生自类 A,因此您无法从父级访问子级的成员:

double A::b(){ 
    return (*elems)-*(elems+1); // elems is a member of B not A
}