我想就我面临的问题提供一些帮助。
我使用带有类Shape和Circle(从形状派生)的polymorph程序进行了继承。所以我有一些像这样的代码
的main.cpp
Shape* shape = new (nothrow) Shape[size]();
input_circle(shape);
show_circle_area(shape);
和main.cpp中的程序
void show_circle_area(Shape *mshape){
int i;
sort(mshape,mshape+totshape,sortByArea);
cout << "CIRCLE" << endl;
for (i=0;i<totshape;i++)
if (dynamic_cast<Circle*> (mshape[i]))
cout << mshape[i].getWidth() << " " << mshape[i].getArea() << " " << mshape[i].getPerimeter() << endl;
}
当我运行这个程序时,我总是遇到这个错误:
main2.cpp: In function 'void output_circle(Shape*)':
main2.cpp:66:39: error: cannot dynamic_cast '*(mshape + ((sizetype)(((unsigned int)i) * 40u)))' (of type 'class Shape') to type 'class Circle*' (source is not a pointer)
if (dynamic_cast<Circle*> (mshape[i]))
^
任何人都可以帮我解决这个问题吗?
main.cpp(已更新)
#include "Shape.h"
#include "Circle.h"
#include "Rectangle.h"
#include "Square.h"
#include <fstream>
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <iomanip>
#include <limits>
#include <typeinfo>
using namespace std;
const int size = 200;
int totshape = 0;
// INPUT FROM FILE
void input_circle(Shape* mshape[]){
ifstream file;
int i;
double r;
file.open("circle.txt");
while (file >> r){
Circle* crl = new (nothrow) Circle(r);
mshape[totshape]=crl;
totshape++;
}
file.close();
}
void input_rectangle(Shape* mshape[]){
ifstream file;
int i;
double w,h;
file.open("rectangle.txt");
while (file >> w >> h){
Rectangle* rec = new (nothrow) Rectangle(w,h);
mshape[totshape]=rec;
totshape++;
}
file.close();
}
void input_square(Shape* mshape[]){
ifstream file;
int i;
double s;
file.open("square.txt");
while (file >> s){
Square* sqr = new (nothrow) Square(s);
mshape[totshape]=sqr;
totshape++;
}
file.close();
}
//OUTPUT TO FILE
void output_circle(Shape *mshape[]){
int i;
ofstream file;
file.open("outcircle.txt");
file << "radius\tarea\tperimeter" << endl;
for (i=0;i<totshape;i++){
if (dynamic_cast<Circle*> (mshape[i]))
file << mshape[i]->getWidth() << "\t" << mshape[i]->getArea() << "\t" << mshape[i]->getPerimeter() << endl;
}
file.close();
}
void output_rectangle(Shape *mshape[]){
int i;
ofstream file;
file.open("outrectangle.txt");
file << "width\theight\tarea\tperimeter" << endl;
for (i=0;i<totshape;i++){
if (dynamic_cast<Rectangle*> (mshape[i]))
file << mshape[i]->getWidth() << "\t" << mshape[i]->getHeight() << "\t" << mshape[i]->getArea() << "\t" << mshape[i]->getPerimeter() << endl;
}
file.close();
}
void output_square(Shape *mshape[]){
int i;
ofstream file;
file.open("outsquare.txt");
file << "sisi\tarea\tperimeter" << endl;
for (i=0;i<totshape;i++){
if (dynamic_cast<Square*> (mshape[i]))
file << mshape[i]->getWidth() << "\t" << mshape[i]->getArea() << "\t" << mshape[i]->getPerimeter() << endl;
}
file.close();
}
//SORTING STL FOR AREA AND PERIMETER
bool sortByArea(Shape lhs[], Shape rhs[]) {
return lhs->getArea() < rhs->getArea();
}
bool sortByPerimeter(Shape lhs[], Shape rhs[]){
return lhs->getArea() < rhs->getArea();
}
//SHOW DATA SORT BY AREA
void show_shape_area(Shape *shape[]){
int i;
sort(shape,shape+totshape,sortByArea);
cout << "ALL SHAPE" << endl;
for (i=0;i<totshape;i++)
cout << shape[i]->getWidth() << " " << shape[i]->getWidth() << " " << shape[i]->getArea() << " " << shape[i]->getPerimeter() << endl;
}
void show_circle_area(Shape *mshape[]){
int i;
sort(mshape,mshape+totshape,sortByArea);
cout << "CIRCLE" << endl;
for (i=0;i<totshape;i++)
if (dynamic_cast<Circle*> (mshape[i]))
cout << mshape[i]->getWidth() << " " << mshape[i]->getArea() << " " << mshape[i]->getPerimeter() << endl;
}
void show_rectangle_area(Shape *mshape[]){
int i;
sort(mshape,mshape+totshape,sortByArea);
cout << "RECTANGLE" << endl;
for (i=0;i<totshape;i++)
if (dynamic_cast<Rectangle*> (mshape[i]))
cout << mshape[i]->getWidth() << " " << mshape[i]->getHeight() << " " << mshape[i]->getArea() << " " << mshape[i]->getPerimeter() << endl;
}
void show_square_area(Shape *mshape[]){
int i;
sort(mshape,mshape+totshape,sortByArea);
cout << "SQUARE" << endl;
for (i=0;i<totshape;i++)
if (dynamic_cast<Square*> (mshape[i]))
cout << mshape[i]->getWidth() << " " << mshape[i]->getArea() << " " << mshape[i]->getPerimeter() << endl;
}
//SHOW DATA SORT BY PERIMETER
void show_shape_perimeter(Shape *shape[]){
int i;
sort(shape,shape+totshape,sortByPerimeter);
cout << "ALL SHAPE" << endl;
for (i=0;i<totshape;i++)
cout << shape[i]->getWidth() << " " << shape[i]->getWidth() << " " << shape[i]->getArea() << " " << shape[i]->getPerimeter() << endl;
}
void show_circle_perimeter(Shape *mshape[]){
int i;
//Shape * tempshape;
sort(mshape,mshape+totshape,sortByPerimeter);
cout << "CIRCLE" << endl;
for (i=0;i<totshape;i++)
//cout << "masuk for" << endl;
//tempshape=&mshape[i];
if (dynamic_cast<Circle*> (mshape[i])){
cout << mshape[i]->getWidth() << " " << mshape[i]->getArea() << " " << mshape[i]->getPerimeter() << endl;
//cout << "masuk" << endl;
}
}
void show_rectangle_perimeter(Shape *mshape[]){
int i;
sort(mshape,mshape+totshape,sortByPerimeter);
cout << "RECTANGLE" << endl;
for (i=0;i<totshape;i++)
if (dynamic_cast<Rectangle*> (mshape[i]))
cout << mshape[i]->getWidth() << " " << mshape[i]->getHeight() << " " << mshape[i]->getArea() << " " << mshape[i]->getPerimeter() << endl;
}
void show_square_perimeter(Shape *mshape[]){
int i;
sort(mshape,mshape+totshape,sortByPerimeter);
cout << "SQUARE" << endl;
for (i=0;i<totshape;i++)
if (dynamic_cast<Square*> (mshape[i]))
cout << mshape[i]->getWidth() << " " << mshape[i]->getArea() << " " << mshape[i]->getPerimeter() << endl;
}
//ADD DATA
void add_circle(Shape *mshape[]){
int input;
cout << endl << "Masukkan jari-jari : ";
while (!(cin >> input) || input < 0) // <<< note use of "short circuit" logical operation here
{
cout << "Input tidak valid" << endl;
cout << "Masukkan jari-jari : ";
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // NB: preferred method for flushing cin
}
Circle* crl = new (nothrow) Circle(input);
mshape[totshape]=crl;
totshape++;
}
void add_rectangle(Shape *mshape[]){
int inwidth, inheight;
cout << endl << "Masukkan panjang : ";
while (!(cin >> inwidth) || inwidth < 0) // <<< note use of "short circuit" logical operation here
{
cout << "Input tidak valid" << endl;
cout << "Masukkan panjang : ";
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // NB: preferred method for flushing cin
}
cout << endl << "Masukkan lebar : ";
while (!(cin >> inheight) || inheight < 0 || !(inheight < inwidth)) // <<< note use of "short circuit" logical operation here
{
cout << "Input tidak valid" << endl;
cout << "Masukkan lebar : ";
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // NB: preferred method for flushing cin
}
Rectangle* rec = new (nothrow) Rectangle(inwidth,inheight);
mshape[totshape]=rec;
totshape++;
}
void add_square(Shape *mshape[]){
int input;
cout << endl << "Masukkan sisi : ";
while (!(cin >> input) || input < 0) // <<< note use of "short circuit" logical operation here
{
cout << "Input tidak valid" << endl;
cout << "Masukkan sisi : ";
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // NB: preferred method for flushing cin
}
Square* sqr = new (nothrow) Square(input);
mshape[totshape]=sqr;
totshape++;
}
//DELETE DATA
//MAIN PROGRAM
int main(){
Shape* shape[size];
input_circle(shape);
input_rectangle(shape);
input_square(shape);
show_shape_area(shape);
show_shape_perimeter(shape);
show_circle_area(shape);
show_circle_perimeter(shape);
show_rectangle_area(shape);
show_rectangle_perimeter(shape);
show_square_area(shape);
show_square_perimeter(shape);
//add_circle(shape);
//show_circle_area(shape);
//add_rectangle(shape);
//show_rectangle_area(shape);
//add_square(shape);
//show_square_area(shape);
output_circle(shape);
output_rectangle(shape);
output_square(shape);
return 0;
}
答案 0 :(得分:1)
你的问题在这里:
mshape[totshape]=crl;
此作业只是将crl
内的“形状部分”复制到mshape[totshape]
,因此mshape[totshape]
仍然是形状,而不是圆形。
为了解决您的问题,请使用Shape *指针数组而不是Shape值:
Shape* shape[size]; // we should write this as size is a const
而且,您的input_***()
功能:
void input_circle(Shape* mshape[]){
ifstream file;
int i;
double r;
file.open("circle.txt");
while (file >> r){
Circle* crl = new Circle(r);
mshape[totshape]=crl;
totshape++;
}
file.close();
}
请注意,函数原型已更改,请为其他函数执行此操作,并使用mshape[i]->foo
代替mshape[i].foo
现在的演员是:if (dynamic_cast<Circle*> (mshape[i])){
在我们使用指针之前,不要忘记在结束之前释放内存:
for (int i = 0; i < totshape; i++) delete mshape[i];
此删除会强制您使Shape的析构函数为虚拟:
class Shape {
public:
virtual ~Shape() {...}
}
否则,Circle,Rectangle ...的析构函数将不会被调用。