只有一个基类函数成员在派生类对象上执行的情况

Only one case of base class function member executing on derived class object

本文关键字:对象 执行 情况 派生 基类 有一个 类函数 成员      更新时间:2023-10-16

我有一个基类Shape的派生类Circle,其中每个类都有自己的print, collide, merge, type等函数。我实例化了一堆Circle对象,并把它们放入一个容器(这是一个指针容器,因为我遇到了对象拼接的麻烦)。在这个方法中,我将对象相互比较并更新属性。所有的派生成员函数都被调用,除了collide,它调用基函数。我打印出collide之前的对象类型,它们都是圆。我不知道为什么衍生的collide不像其他方法一样被调用。

在下面的代码中,type()方法的输出是Circle

调用collide和其他方法的函数。

void calculateGravitationalAttractions(ShapeContainer &shapeContainer) {
    double G = constants::gravitationalConstant;
    double distance, diffX, diffY, tempAx, tempAy;
    double Fnet;    //Net Force on body
    double theta;   //Angle between two points in 2-D space
    double accel;   //Net acceleration of body
    double distanceBetweencb, collisionDistance;
    std::list<Shape*>::iterator ii;
    std::list<Shape*>::iterator jj;
    std::list<Shape*> container = shapeContainer.container;
    //int callCount = 0;
    for(ii = container.begin(); ii != container.end(); ++ii) {
        tempAx = tempAy = 0;
        for(jj = container.begin(); jj != container.end(); ++jj) {
            if((*ii) != (*jj)) {
                //callCount++;
                (*ii)->type();
                (*jj)->type();
                if (!(*ii)->collide(*(*jj))) {
                    diffX = (*ii)->pos[0] - (*jj)->pos[0];
                    diffY = (*ii)->pos[1] - (*jj)->pos[1];
                    distance = sqrt((diffX * diffX) + (diffY * diffY));
                    Fnet = ((G * (*ii)->mass * (*jj)->mass)) / distance;
                    theta = atan2(diffY, diffX);
                    accel = Fnet / (*ii)->mass;                     
                    tempAx += -(accel * cos(theta));
                    tempAy += -(accel * sin(theta));
                } else { //if they collide
                    if((*ii)->mass > (*jj)->mass) {
                        (*ii)->merge(*(*jj));
                        jj = container.erase(jj);
                    } else {
                        (*jj)->merge(*(*ii));
                        ii = container.erase(ii);
                    }
                }
            }
        }
        //printf("n %f, %f, n", tempAx, tempAy);
        (*ii)->accel[0] = tempAx;
        (*ii)->accel[1] = tempAy;
    }
    //printf("Container size is %dn", container.size());
    //printf("Callcount is %dnn", callCount);
}

我的ShapeCircle类。

typedef array<double, 2> Vector;    
class Shape {
    public:
        Vector pos;
        Vector vel;
        Vector accel;
        double mass;
        bool move;
        SDL_Color color;
        Shape() {}
        Shape(Vector Pos, Vector Vel, Vector Accel, double Mass, bool Move, SDL_Color Color) {
            pos = Pos;
            vel = Vel;
            accel = Accel;
            mass = Mass;
            move = true;
            color = Color;
        }
        virtual void print() {
            printf("Type: Shapen");
            printf("xPos: %f, yPos: %fn", pos[0], pos[1]);
            printf("xVel: %f, yVel: %fn", vel[0], vel[1]);
            printf("xAccel: %f, yAccel: %fn", accel[0], accel[1]);
            printf("mass: %fnn", mass);
        }
        virtual void render(SDL_Renderer* renderer) {
            //printf("Rendering shape.n");
        }
        virtual bool collide(Shape &a) { //true if the shapes collide
                printf("Checking collision of shape.n");
                double xDiff = pos[0] - a.pos[0];
                double yDiff = pos[1] - a.pos[1];
                if (sqrt((xDiff * xDiff) + (yDiff * yDiff) < 100)) {
                    return true;
                } else {
                    return false;
            }
        }

            virtual void merge(Shape &a) {
            color.r = (color.r * mass + a.color.r * a.mass) / (mass + a.mass);
            color.g = (color.g * mass + a.color.g * a.mass) / (mass + a.mass);
            color.b = (color.b * mass + a.color.b * a.mass) / (mass + a.mass);
            mass += a.mass;
            printf("Merging shapes.");
        }
        virtual void type() {
            cout << "Type: Shapen";    
        }

};
class Circle: public Shape {
 public:
    double radius;
    Circle() {}
    Circle(Vector Pos, Vector Vel, Vector Accel, double Mass, bool Move, SDL_Color Color) {
        pos = Pos;
        vel = Vel;
        accel = Accel;
        mass = Mass;
        radius = sqrt(mass) * constants::radiusFactor;
        move = true;
        color = Color;
    }

    void print() {
        printf("Type: Circlen");
        printf("xPos: %f, yPos: %fn", pos[0], pos[1]);
        printf("xVel: %f, yVel: %fn", vel[0], vel[1]);
        printf("xAccel: %f, yAccel: %fn", accel[0], accel[1]);
        printf("mass: %fn", mass);
        printf("radius: %fnn", radius);
  }
    void render(SDL_Renderer* renderer) {
        //printf("Rendering circle.n");
        int success = filledCircleRGBA(renderer, (int) pos[0], (int) pos[1], 
                (int) radius, color.r, color.g, color.b, 255);  
    }

        bool collide(Circle &a) { //true if the shapes collide
        printf("Checking collision of circle.n");
        double xDiff = pos[0] - a.pos[0];
        double yDiff = pos[1] - a.pos[1];
        if (sqrt((xDiff * xDiff) + (yDiff * yDiff) < radius + a.radius)) {
            return true;
        } else {
            return false;
        }
    }
    void merge(Circle &a) {
            printf("Merging circles.");
            //momentum calculations
            double xVel = vel[0]*mass + a.vel[0]*a.mass;
            double yVel = vel[1]*mass + a.vel[1]*a.mass;
            double totalMass = mass + a.mass ;
            vel[0] = xVel / mass * constants::frictionFactor;
            vel[1] = yVel / mass * constants::frictionFactor;
            //merge colors
            color.r = (color.r * mass + a.color.r * a.mass) / (mass+a.mass);
            color.g = (color.g * mass + a.color.g * a.mass) / (mass+a.mass);
            color.b = (color.b * mass + a.color.b * a.mass) / (mass+a.mass);
            mass += a.mass;
    }
    void type() {
            cout << "Type: Circlen";   
    }

所有派生的成员函数都被调用,除了collision

那是因为你实际上并没有重写在Circle子类中的collision方法:

class Shape {
    virtual bool collide(Shape &a) { ... 
class Circle: public Shape { 
    bool collide(Circle &a) { ... 

签名不同,方法不同。