我试图在同一基类的不同子类之间实现比较。如果两个实例具有不同的子类,则比较应返回false
,如果它们属于同一子类,则返回实际比较结果。
检查函数main中的最后一行:虽然我已将equalTo
声明为virtual
,但只调用基类的equalTo
方法。我的错是什么?
提前致谢。
#include <iostream>
#include <fstream>
#include <cmath>
#include <limits>
#include <sstream>
#include <stdexcept>
#include <algorithm>
using namespace std;
bool fileInput = false, fileOutput = false;
class Point
{
public:
double x,y;
Point(){};
Point(double x1, double y1) {
x=x1;
y=y1;
}
bool operator==(Point other) const
{
return (abs(x - other.x) < numeric_limits<double>::epsilon()) and (abs(y - other.y) < numeric_limits<double>::epsilon());
}
};
class Shape
{
protected:
virtual double area() const
{
return 0;
}
virtual void print(std::ostream& os) const {}
virtual void read(std::istream& is) {}
public:
bool compare(Shape* other) {
return area() < other->area();
}
virtual bool equalTo(Shape other) const {
cout << "original";
return false;
}
friend std::ostream& operator<<(std::ostream &strm, const Shape &t)
{
t.print(strm);
return strm;
}
friend std::istream& operator>>(std::istream &strm, Shape &t)
{
t.read(strm);
return strm;
}
};
class Circle : public Shape
{
Point c;
double r;
double area() const
{
return M_PI * r * r;
}
void print(std::ostream &strm) const
{
strm << "Circle. Center coordinates: (" << c.x << "," << c.y << "). Radius: " << r << ". Area: " << area();
}
void read(std::istream &strm)
{
if (!fileInput) cout << "Enter Circle\nCenter: ";
strm >> c.x >> c.y;
if (!fileInput) cout << "Radius: ";
strm >> r;
if (r<0)
throw std::invalid_argument( "The radius cannot be negative." );
}
public:
Circle() {}
Circle(Point x, double y)
{
c = x;
r = y;
}
bool equalTo(Shape other1) const
{
Circle* other = dynamic_cast<Circle*>(&other1);
if (other == 0) return false;
return (c == other->c) and (abs(r - other->r)<numeric_limits<double>::epsilon());
}
};
class Hexagon : public Shape
{
Point c;
double r;
double area() const
{
return 1.5 * sqrt(3) * r * r;
}
void print(std::ostream &strm) const
{
strm << "Hexagon. Center coordinates: (" << c.x << "," << c.y << "). Circumcircle radius: " << r << ". Area: " << area();
}
void read(std::istream &strm)
{
if (!fileInput) cout << "Enter Hexagon\nCenter: ";
strm >> c.x >> c.y;
if (!fileInput) cout << "Circumcircle radius: ";
strm >> r;
if (r<0)
throw std::invalid_argument( "The circumcircle radius cannot be negative." );
}
public:
Hexagon() {}
Hexagon(Point x, double y)
{
c = x;
r = y;
}
bool equalTo(Shape other1) const
{
Hexagon* other = dynamic_cast<Hexagon*>(&other1);
if (other == 0) return false;
return (c == other->c) and (abs(r - other->r)<numeric_limits<double>::epsilon());
}
};
int main()
{
Shape c1 = Circle(Point(0,0), 3);
Shape c2 = Circle(Point(0,0), 3);
Shape c3 = Hexagon(Point(0,0), 3);
cout << "circles: " << c1.equalTo(c2) << endl << "diff: " << c1.equalTo(c3) << endl;
}
答案 0 :(得分:3)
这是切片,当您将对象分配给类型为Shape
的对象时 - 对象被切成Shape
。使用指针,或者可以是引用。
Circle p1(Point(0, 0), 3);
Circle p2(Point(0, 0), 3);
Hexagon h1(Point(0, 0), 3);
Shape& c1 = p1;
Shape& c2 = p2;
Shape& c3 = h1;
答案 1 :(得分:1)
当您从派生类中复制构造Shape
时,该对象将切片,以便仅保留它的Shape
部分。然后当你调用equalTo
时,该函数是静态绑定的。
要调用衍生版本,请将c1
和朋友加入Shape&
。