不能将变量声明为类的抽象

Cannot declare variable to be an abstract of class

本文关键字:抽象 声明 变量 不能      更新时间:2023-10-16

我是c++的新手。我正试图创建另一个对象,但它以某种方式阻止了我这样做。它有这个。它不能将变量"rq"声明为抽象类型"Rectangle",因为以下虚拟函数在"Rectanger"中是纯的。

这是图书馆的

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <stdlib.h>
#include <ctime>
using namespace std;

这是超类

class Shape {
protected:
char area[20][20];
int htri,ss,width,length;
public:
virtual void printRectangle() = 0;
virtual void printSquare() = 0;
void sethtri(int t){
htri = t;
}
void setss(int s){
ss = s;
}
void setwidth(int w){
width = w;
}
void setlength(int l){
length = l;
}
int gethtri(){
return htri;
}
int getlength(){
return length;
}
int getwidth(){
return width;
}
int getss(){
return ss;
}
};

这是的一个子类

class Rectangle:public Shape
{
protected:
int raziq;
public:
void printRectangle()
{
raziq = rand() % 21;
for (int i = 0 + raziq; i <= length + raziq; i++)
{
for (int j = 0 + raziq; j <= width + raziq; j++)
{
area[i][j] = 'C';
}
}
for (int i = 0; i <= 20; i++)
{
for (int j = 0; j <= 20; j++)
{
if (area[i][j] != 'C')
{
area[i][j] = '-';
}
}
}
for (int i=0; i<20; i++)
{
for (int j=0; j<20; j++)
{
cout << area[i][j];
}
cout << endl;
}
}
};

这是另一个子类

class Square:public Shape
{
protected:
int raziq;
public:
void printSquare()
{
raziq = rand() % 21;
for (int i = 0 + raziq; i <= ss + raziq; i++)
{
for (int j = 0 + raziq; j <= ss + raziq; j++)
{
area[i][j] = 'C';
}
}
for (int i = 0; i <= 20; i++)
{
for (int j = 0; j <= 20; j++)
{
if (area[i][j] != 'C')
{
area[i][j] = '-';
}
}
}
for (int i=0; i<20; i++)
{
for (int j=0; j<20; j++)
{
cout << area[i][j];
}
cout << endl;
}
}
};

int main(){
int t,s,w,l;
ofstream keluar;
ifstream masuk;
masuk.open("value.txt");
if (masuk.is_open())
{
cout << "File value is open n";
masuk >> t >> s >> w >> l;
masuk.close();
}
else
{
cout << "Unable to open file" << endl;
}

矩形rq 上的错误就在这里

srand(time(NULL));
Rectangle rq;
Shape *s1 = &rq;
s1->sethtri(t);
s1->setlength(l);
s1->setss(s);
s1->setwidth(w);
s1->printRectangle();
Square sq;
Shape *s2 = &sq;
s2->sethtri(t);
s2->setlength(l);
s2->setss(s);
s2->setwidth(w);
s2->printSquare();


return 0;

}

如果我们不覆盖派生类中的纯虚拟函数,那么派生类也变成了抽象类。

矩形是从shape派生而来的,shape包含两个纯虚拟函数,因此必须在矩形类中同时实现printRectangle()printsquare()函数。否则它也将成为抽象类

您还需要在矩形和正方形类中实现printsquare()方法,然后您可以制作这些类的对象。

class Square:public Shape
{
public:
void printRectangle() override;
void printSquare() override;
};
class Rectangle:public Shape
{
public:
void printRectangle() override;
void printSquare() override;
};

为什么要覆盖矩形类中的printsquare()函数,反之亦然?毫无意义

源Abstract类c++

更好的做法是在派生类中重写函数的签名中添加override关键字。在这种情况下,如果在派生类中错误地更改了签名,编译器将给出错误。

在这种情况下:

class Shape
{
public:
virtual void printRectangle() = 0;
virtual void printSquare() = 0;
}
class Square:public Shape
{
public:
void printRectangle() override;
void printSquare() override;
};

请参见此处:https://en.cppreference.com/w/cpp/language/override

您的设计有问题!

  1. 假设您想添加更多的形状,例如CircleEllipsisTriangle,也许是通用的Polygone–你真的想在每次添加新形状(printCircleprintTriangle…)时扩展基类吗???

  2. Hamza.S的答案(这是给出的问题的答案,我在这里再看一点…)已经说明了为什么不能实例化子类,通过让派生类覆盖所有纯虚拟函数来解决这个问题。但是,为什么圆形应该打印正方形,三角形应该打印矩形。。。这毫无意义。

所以你应该考虑一个完整的重新设计:

class Shape
{
public:
virtual ~Shape() = default; // important: add a virtual destructor!!!
virtual void print() = 0;
};
class Square : public Shape
{
public:
void print() override; // prints a square
};
class Circle : public Shape
{
public:
void print() override; // prints a circle
};

关于受保护的成员:您应该只保留每个形状所需的成员。一个正方形只需要宽度和长度中的一个,一个圆形不需要,而是一个半径,三角形至少需要三个参数来唯一识别它

如果您只有正方形和矩形,并且100%确信不会添加其他形状,那么在基类中保留更多这些成员(以及getter/setter to)可能是有意义的–但这取决于你的决定。。。