如何正确访问c++中继承的方法和构造函数

How do I properly access inherited methods and constructors in c++?

本文关键字:方法 构造函数 继承 何正确 访问 c++      更新时间:2023-10-16

我有一个Sphere类,它继承了中心的Point对象。当我通过Sphere构造函数创建Sphere对象时,它总是将中心初始化为0,0,0,但它会正确地设置半径。

访问Sphere的setCenter()方法也没有影响。我能有效地更改球体中心点的X、Y、Z坐标的唯一方法是调用该点的setX()等方法。

如果这是一个显而易见的答案,我很抱歉,但我是C++的新手,正在为过渡而挣扎。如果我遗漏了任何重要信息,请毫不犹豫地告诉我。以下是相关代码:

主要

#include <iostream>
#include <fstream>
#include "MovingSphere.h"
using namespace std;
int main() {
    ifstream inFile("sphere.txt");
    int X, Y, Z, R, DX, DY, DZ;
    if (inFile) {
        inFile >> X >> Y >> Z >> R
            >> DX >> DY >> DZ;
    }
    else {
        cerr << "neRR: Cannot find input file.nn";
    }
    // create a sphere
    Sphere sphereInstance(X, Y, Z, R);
    sphereInstance.setCenter(1, 2, 3);
    sphereInstance.setX(3);
    cout << endl <<
        "X = " << sphereInstance.getX() << endl <<
        "Y = " << sphereInstance.getY() << endl <<
        "Z = " << sphereInstance.getZ() << endl;
return 0;
}

点.cpp

#include "Point.h"
Point::Point() : x(0), y(0), z(0) {   // default constructor (point at 0,0,0)
}
Point::Point(int X, int Y) : x(), y(), z(0) {      // constructor for 2d point
}
Point::Point(int X, int Y, int Z) : x(), y(), z() { // constructor for 3d point
}
// set the points X coordinate (mutator)
void Point::setX(int newX) {
    x = newX;
}
... etc.

点.h

#ifndef POINT_H
#define POINT_H
class Point {
public:
    Point ();                         // default constructor (0,0,0);
    Point(int X, int Y);              // constructor for 2d point
    Point(int X, int Y, int Z);       // constructor for 3d point
    void setX(int newX);              // declaration
    int getX() const;                 // declaration
etc...

private:
    int x, y, z;  // coordinates of point
};
#endif  /* POINT_H */

Sphere.cpp

#define _USE_MATH_DEFINES
#include <math.h>
#include "Sphere.h"
Sphere::Sphere() : 
    center(), radius(0) {// default constructor (a point at 0,0,0)
}
Sphere::Sphere(int X, int Y, int Z, int R) {     // sphere constructor
    center = Point(X, Y, Z);
    radius = R;
}
// set the sphere's center (mutator)
void Sphere::setCenter(int X, int Y, int Z) {
    center.setX(X);
    center.setY(Y);
    center.setZ(Z);
}
... etc.

Sphere.h

#ifndef SPHERE_H
#define SPHERE_H
#include "Point.h"
class Sphere: public Point {
public:
    Sphere();          // default constructor (a point at 0,0,0)
    Sphere (int X, int Y, int Z, int R); // sphere constructor
    void setRadius(int newRadius); // declaration
    void setCenter(int X, int Y, int Z); // declaration
    int getRadius() const;         // declaration
private:
    Point center;      // center of sphere
    int radius;        // radius of sphere
};
#endif  /* SPHERE_H */

输出

X = 3
Y = 0
Z = 0
class Sphere: public Point {

这意味着球体一个点,并从一个点所拥有的一切开始,包括X、Y和Z坐标。

private:
   Point center;      // center of sphere

这意味着球体有一个点,称为center。球体的这个点也有一个X、Y和Z坐标,就像所有的点一样

因此,球体既是一个点,又有一个点。每个点都有一个X、Y和Z坐标。这不可能是你想要的,当你的代码设置了这两点中的一个,然后得到另一个时,它就会失败。。选择一个型号并坚持下去。

如果你需要像对待点一样对待球体,那么去掉center——在这个模型中,球体是一个也有半径的点。如果你不需要像对待点一样对待球体,那么不要从点继承——在这个模型中,球体不是一个点,而是有一个点和一个半径。

您的Point 2和3参数构造函数不处理输入。将其更改为

Point::Point(int X, int Y) : x(X), y(Y), z(0) { }
Point::Point(int X, int Y, int Z) : x(X), y(X), z(Z) { }

如果centerSpherePoint数据成员,那么您应该更喜欢构造函数初始化列表中的初始化,而不是构造函数主体中的赋值:

Sphere::Sphere(int X, int Y, int Z, int R) : center(X,Y,Z), radius(R) { }

我在语句中编辑了一个冒号,但至少需要6个字符。

您没有显示PointSphere是如何关联的,但我猜Sphere继承自Point。。。

class Point
{
    ...
};
class Sphere : public Point
{
    ...
};

如果你想调用例如基本构造函数,你可以在初始化器列表中调用:

Sphere::Sphere(int X, int Y, int Z, int R)
    : Point(X, Y, Z), radius(R)
{
}

至于其他函数,如果它们在基类中,则可以将它们当作子类的成员来使用:

void Sphere::setCenter(int X, int Y, int Z)
{
    setX(X);
    setY(Y);
    setZ(Z);
}

由于Sphere也是Point(由于继承),因此不需要center成员变量。

正如其他人所说,您应该首先明确Sphere与Point的关系(要么Sphere有一个Point,即成员,要么Sphere是一个Point(即继承))。

然而,你的确切问题是:

  • Sphere的setCenter()方法更新Sphere::center
  • Sphere使用Point的getX/Y/Z(),这些使用Point中的x/Y/Z

也就是说,setCenter()更新与getX/Y/Z()无关的内容。