我是C ++的新手。我正在尝试创建另一个对象,但是它以某种方式阻止了我这样做。它不能声明变量'rq'为抽象类型'Rectangle',因为以下虚拟函数在'Rectangle'中是纯净的。
这是图书馆
#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;
}
答案 0 :(得分:1)
如果我们不重写派生类中的纯虚函数, 然后派生类也将成为抽象类。
Rectangle是从shape派生的,并且shape包含两个纯虚函数,因此必须在矩形类中同时实现var c=$(".round-slider");
$(".circle-1").on("click", function () {
"240" === c.attr("data-rotate").slice(3) && c.attr("data-rotate", "deg120"),
"-120" === c.attr("data-rotate").slice(3) && c.attr("data-rotate", "deg-240"),
"0" === c.attr("data-rotate").slice(3) && c.attr("data-rotate", "deg120"),
"360" !== c.attr("data-rotate").slice(3) && "-360" !== c.attr("data-rotate").slice(3) || (c.addClass("stopTransition"),
c.attr("data-rotate", "deg0"),
setTimeout(function () {
c.removeClass("stopTransition"), c.attr("data-rotate", "deg120")
}, 10)),
setTimeout(function () {
c.addClass("slide-3"), c.removeClass("slide-1 slide-2")
}, 15)
})
和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;
};
函数,反之亦然?没道理
答案 1 :(得分:0)
更好的做法是在派生类的重写函数的签名中添加override关键字。在这种情况下,如果在派生类中错误地更改了签名,则编译器将给出错误。
在这种情况下:
class Shape
{
public:
virtual void printRectangle() = 0;
virtual void printSquare() = 0;
}
class Square:public Shape
{
public:
void printRectangle() override;
void printSquare() override;
};
答案 2 :(得分:0)
您的设计有问题!
假设您要添加其他形状,例如。 G。 Circle
,Ellipsis
,Triangle
,也许是通用的Polygone
–您是否真的想在每次添加新形状时扩展基类(printCircle
, printTriangle
,...)???
Hamza.S的answer(这是给出的问题,我在这里再看一下...)已经显示了为什么您无法实例化孩子类,通过允许派生类覆盖 all 纯虚拟函数来解决此问题。但是,为什么要用圆圈打印一个正方形,一个三角形打印一个矩形,……那只是没有意义。
因此,您应该考虑进行彻底的重新设计:
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的对象)可能是有意义的-但这已经到了由您决定...