只有一个基类函数成员在派生类对象上执行的情况
Only one case of base class function member executing on derived class object
我有一个基类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);
}
我的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: 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) { ...
签名不同,方法不同。
相关文章:
- 如何将成员函数作为参数传递并在派生对象上执行方法列表
- mingw32-make 使用"MinGW Makefiles"生成器跟踪 CMAKE 无法将可执行文件链接到对象库
- 如果普通默认构造函数不执行任何操作,为什么我们不能使用 malloc 创建平凡可构造的对象?
- 在Qt中执行完所有插槽后,如何释放对象
- 如何使用智能指针对象执行成员函数指针
- 在多个对象上执行同一语句的零成本抽象
- 如何执行矢量<类对象*>深层复制
- 在C++中,系统如何将这些对象中的每一个与执行程序的窗口相关联?
- 访问执行策略for_each函数对象中的迭代器
- 模板函数,用于在模板化对象上执行成员回调,而无需提供其实例
- CUDA编译器对象可执行
- C++模板的对象代码是否在可执行文件和动态库中重复?
- 执行输入检查并在C++中初始化对象
- 通过引用派生类对象从基类对象执行向下转换时引发bad_cast异常
- 方法从C 中的另一个对象执行
- 当静态对象执行静态对象时,崩溃
- 用于对基于I/O的对象执行一系列操作的设计模式
- 正确重复使用ADODB命令对象执行多个查询
- 同时为队列中的对象执行函数时出现奇怪的行为
- 一次对所有对象执行一个函数(没有for循环)