我有一个基类Circle
的派生类Shape
,其中每个类都有自己的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 %d\n", container.size());
//printf("Callcount is %d\n\n", callCount);
}
我的
Shape
和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";
}
最佳答案
除碰撞以外,我所有的派生成员函数都被调用
那是因为您实际上并未覆盖Circle子类中的collide方法:
class Shape {
virtual bool collide(Shape &a) { ...
class Circle: public Shape {
bool collide(Circle &a) { ...
不同的签名,不同的方法。