只有一种基类函数成员在派生类对象上执行

时间:2015-07-29 09:00:09

标签: c++ polymorphism virtual-functions

我有一个基类Circle的派生类Shape,其中每个类都有自己的printcollidemerge,{{1}等功能。我实例化了一堆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 %d\n", container.size()); //printf("Callcount is %d\n\n", callCount); } Shape类。

Circle

1 个答案:

答案 0 :(得分:2)

  

除了碰撞

之外,我的所有派生成员函数都被调用

那是因为你实际上没有覆盖你的Circle子类中的碰撞方法:

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";   
    }

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