虚拟派生函数和包含循环
Virtual derived functions and include loops
我目前正在学习 C++,但遇到了问题。
这是我的问题:
- 我有一个 class 点(如下所述)
- 我有一个 class 继承自 Point
的笛卡尔坐标和极坐标
我需要创建一个函数,将笛卡尔坐标转换为极坐标,将极坐标转换为笛卡尔坐标。它需要直接从 Cartesian 和 Polar 或 Point 调用。
这是我现在大致得到的(无法编译):
// point.hpp
class Point {
public:
virtual void display(std::ostream&) const = 0;
virtual void convert(Cartesian&) const = 0;
virtual void convert(Polar&) const = 0;
friend std::ostream& operator<<(std::ostream&, const Point&);
};
// cartesian.hpp
class Cartesian : public Point {
private:
double _x;
double _y;
public:
Cartesian();
Cartesian(const double, const double);
void display(std::ostream&) const;
void convert(Polar&) const override;
void setX(const double);
void setY(const double);
double getX() const;
double getY() const;
};
// polar.hpp
class Polar : public Point {
private:
double _a;
double _d;
public:
Polar();
Polar(const double, const double);
void display(std::ostream&) const;
void convert(Cartesian&) const override;
void setAngle(const double);
void setDistance(const double);
double getAngle() const;
double getDistance() const;
};
我知道设计很糟糕,但我无法更改它。
这是要通过的单元测试:
TEST_CASE ( "TP1_Point::ConversionVersPolaire_V1" ) {
const double x = 12.0;
const double y = 24.0;
const double a = 63.434948;
const double d = 26.832815;
const Cartesian c(x,y);
Polar p;
c.convert(p);
REQUIRE ( p.getAngle() == Approx(a).epsilon(1e-3) );
REQUIRE ( p.getDistance() == Approx(d).epsilon(1e-3) );
}
//-----------------------------------------------------------------------------------------------
TEST_CASE ( "TP1_Point::ConversionVersCartesien_V1" ) {
const double a = 12.0;
const double d = 24.0;
const double x = 23.475542;
const double y = 4.9898805;
const Polar p(a,d);
Cartesian c;
p.convert(c);
REQUIRE ( c.getX() == Approx(x).epsilon(1e-3) );
REQUIRE ( c.getY() == Approx(y).epsilon(1e-3) );
}
//-----------------------------------------------------------------------------------------------
TEST_CASE ( "TP1_Point::ConversionVirtuel" ) {
const double x = 12.0;
const double y = 24.0;
const double a = 63.434948;
const double d = 26.832815;
Cartesian c(x,y);
Polar p(a,d);
const Point * x1 = &c;
const Point * x2 = &p;
Cartesian c1;
Cartesian c2;
Polar p1;
Polar p2;
x1->convert(c1);
x1->convert(p1);
x2->convert(c2);
x2->convert(p2);
REQUIRE ( c1.getX() == Approx(x).epsilon(1e-3) );
REQUIRE ( c1.getY() == Approx(y).epsilon(1e-3) );
REQUIRE ( c2.getX() == Approx(x).epsilon(1e-3) );
REQUIRE ( c2.getY() == Approx(y).epsilon(1e-3) );
REQUIRE ( p1.getAngle() == Approx(a).epsilon(1e-3) );
REQUIRE ( p1.getDistance() == Approx(d).epsilon(1e-3) );
REQUIRE ( p2.getAngle() == Approx(a).epsilon(1e-3) );
REQUIRE ( p2.getDistance() == Approx(d).epsilon(1e-3) );
}
提前感谢您的回答。
在成员函数的这些声明中
virtual void convert(Cartesian&) const = 0;
virtual void convert(Polar&) const = 0;
名称 Cartesian 和 Polar 尚未声明。
您需要在 class 点之前将它们作为前向声明引入
class Cartesian;
class Polar;
或者在函数声明中使用详尽的类型名称,例如
virtual void convert( class Cartesian& ) const = 0;
virtual void convert( class Polar& ) const = 0;
由于函数显示也是虚拟的,因此您应该在其派生的声明中使用关键字 override classes。
void display(std::ostream&) const override;
此外,如果其中一个函数 convert 未在派生的 classes 之一中被覆盖,则相应的 class 仍将是抽象的。
我目前正在学习 C++,但遇到了问题。
这是我的问题:
- 我有一个 class 点(如下所述)
- 我有一个 class 继承自 Point 的笛卡尔坐标和极坐标
我需要创建一个函数,将笛卡尔坐标转换为极坐标,将极坐标转换为笛卡尔坐标。它需要直接从 Cartesian 和 Polar 或 Point 调用。
这是我现在大致得到的(无法编译):
// point.hpp
class Point {
public:
virtual void display(std::ostream&) const = 0;
virtual void convert(Cartesian&) const = 0;
virtual void convert(Polar&) const = 0;
friend std::ostream& operator<<(std::ostream&, const Point&);
};
// cartesian.hpp
class Cartesian : public Point {
private:
double _x;
double _y;
public:
Cartesian();
Cartesian(const double, const double);
void display(std::ostream&) const;
void convert(Polar&) const override;
void setX(const double);
void setY(const double);
double getX() const;
double getY() const;
};
// polar.hpp
class Polar : public Point {
private:
double _a;
double _d;
public:
Polar();
Polar(const double, const double);
void display(std::ostream&) const;
void convert(Cartesian&) const override;
void setAngle(const double);
void setDistance(const double);
double getAngle() const;
double getDistance() const;
};
我知道设计很糟糕,但我无法更改它。
这是要通过的单元测试:
TEST_CASE ( "TP1_Point::ConversionVersPolaire_V1" ) {
const double x = 12.0;
const double y = 24.0;
const double a = 63.434948;
const double d = 26.832815;
const Cartesian c(x,y);
Polar p;
c.convert(p);
REQUIRE ( p.getAngle() == Approx(a).epsilon(1e-3) );
REQUIRE ( p.getDistance() == Approx(d).epsilon(1e-3) );
}
//-----------------------------------------------------------------------------------------------
TEST_CASE ( "TP1_Point::ConversionVersCartesien_V1" ) {
const double a = 12.0;
const double d = 24.0;
const double x = 23.475542;
const double y = 4.9898805;
const Polar p(a,d);
Cartesian c;
p.convert(c);
REQUIRE ( c.getX() == Approx(x).epsilon(1e-3) );
REQUIRE ( c.getY() == Approx(y).epsilon(1e-3) );
}
//-----------------------------------------------------------------------------------------------
TEST_CASE ( "TP1_Point::ConversionVirtuel" ) {
const double x = 12.0;
const double y = 24.0;
const double a = 63.434948;
const double d = 26.832815;
Cartesian c(x,y);
Polar p(a,d);
const Point * x1 = &c;
const Point * x2 = &p;
Cartesian c1;
Cartesian c2;
Polar p1;
Polar p2;
x1->convert(c1);
x1->convert(p1);
x2->convert(c2);
x2->convert(p2);
REQUIRE ( c1.getX() == Approx(x).epsilon(1e-3) );
REQUIRE ( c1.getY() == Approx(y).epsilon(1e-3) );
REQUIRE ( c2.getX() == Approx(x).epsilon(1e-3) );
REQUIRE ( c2.getY() == Approx(y).epsilon(1e-3) );
REQUIRE ( p1.getAngle() == Approx(a).epsilon(1e-3) );
REQUIRE ( p1.getDistance() == Approx(d).epsilon(1e-3) );
REQUIRE ( p2.getAngle() == Approx(a).epsilon(1e-3) );
REQUIRE ( p2.getDistance() == Approx(d).epsilon(1e-3) );
}
提前感谢您的回答。
在成员函数的这些声明中
virtual void convert(Cartesian&) const = 0;
virtual void convert(Polar&) const = 0;
名称 Cartesian 和 Polar 尚未声明。
您需要在 class 点之前将它们作为前向声明引入
class Cartesian;
class Polar;
或者在函数声明中使用详尽的类型名称,例如
virtual void convert( class Cartesian& ) const = 0;
virtual void convert( class Polar& ) const = 0;
由于函数显示也是虚拟的,因此您应该在其派生的声明中使用关键字 override classes。
void display(std::ostream&) const override;
此外,如果其中一个函数 convert 未在派生的 classes 之一中被覆盖,则相应的 class 仍将是抽象的。