我有一个基类Circle的派生类Shape,其中每个类都有自己的printcollidemergetype等功能。我实例化了一堆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 %d\n", container.size());
    //printf("Callcount is %d\n\n", 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: Shape\n");
            printf("xPos: %f, yPos: %f\n", pos[0], pos[1]);
            printf("xVel: %f, yVel: %f\n", vel[0], vel[1]);
            printf("xAccel: %f, yAccel: %f\n", accel[0], accel[1]);
            printf("mass: %f\n\n", 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: Shape\n";
        }


};

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: Circle\n");
        printf("xPos: %f, yPos: %f\n", pos[0], pos[1]);
        printf("xVel: %f, yVel: %f\n", vel[0], vel[1]);
        printf("xAccel: %f, yAccel: %f\n", accel[0], accel[1]);
        printf("mass: %f\n", mass);
        printf("radius: %f\n\n", 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: Circle\n";
    }

最佳答案

除碰撞以外,我所有的派生成员函数都被调用


那是因为您实际上并未覆盖Circle子类中的collide方法:

class Shape {
    virtual bool collide(Shape &a) { ...

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


不同的签名,不同的方法。

10-06 04:08