5

首先,如果答案很明显,我想提前道歉;我对 C++ 很陌生,我的第一语言是 Java。我也是 Stack Overflow 的新手,所以如果我的问题有问题或者您需要其他任何东西,请告诉我。

所以。我在这里有这段代码:(我将 SFML 用于向量和 CircleShape)

Ball::Ball() {

    // This ugly thing calls the full constructor with a random x and y position
    // in such a way the the entire ball is inside the screen.

    Ball::Ball((rand() % (WINDOW_X - (2 * BALL_RADIUS))) + BALL_RADIUS, (rand() % (WINDOW_Y - (2 * BALL_RADIUS))) + BALL_RADIUS);

}
Ball::Ball(float x, float y) {

    loc.x = x;
    loc.y = y;

    ball.setPosition(loc.x - BALL_RADIUS, loc.y - BALL_RADIUS);
    ball.setRadius(BALL_RADIUS);
    ball.setFillColor(sf::Color::Red);
    ball.setOutlineColor(sf::Color::Black);
    ball.setOutlineThickness(1);

}

这是标题(#included 到上面的文件中):

class Ball {

private:
    sf::CircleShape ball;
    sf::Vector2f loc;
    sf::Vector2f vel;
    sf::Vector2f acc;

    void update();
    void bounce();
    void draw();

public:
    Ball();
    Ball(float x, float y);
    void run();

};

当我用

Ball ball;

(是的,所有 SFML 渲染的东西都有效),它从不显示。一点调查表明,它的 loc.x 和 loc.y 变量没有设置,可能球对象的半径、填充颜色等也没有设置。如果我在构造函数中使用 std::cout 打印这些值,则 loc.x 和 loc.y 以及所有其他值都已设置,因此我假设它们在构造函数之后的某处未设置。奇怪的是,如果我用

Ball ball((rand() % (WINDOW_X - (2 * BALL_RADIUS))) + BALL_RADIUS, (rand() % (WINDOW_Y - (2 * BALL_RADIUS))) + BALL_RADIUS);

甚至

Ball ball(400, 300);

一切正常,球出现在屏幕上。我真的很难过伙计们。如果有人可以帮助我,那就太好了。

顺便说一句,我正在运行带有 Xcode 4.5.2 的 OS X 10.8,并使用 SFML RC2.0,如果这有什么不同的话。

谢谢,

马特

4

7 回答 7

7

在 C++11 之前,从另一个构造函数调用构造函数(称为委托构造函数)是不可能的。要在 C++11 中执行此操作,您需要使用成员初始化列表:

Ball::Ball()
 : Ball((rand() % (WINDOW_X - (2 * BALL_RADIUS))) + BALL_RADIUS,
        (rand() % (WINDOW_Y - (2 * BALL_RADIUS))) + BALL_RADIUS)
{ }

在 C++11 之前,您可以创建另一个执行常见工作的函数并让两个构造函数都调用它。

Ball::Ball() {
  init((rand() % (WINDOW_X - (2 * BALL_RADIUS))) + BALL_RADIUS,
       (rand() % (WINDOW_Y - (2 * BALL_RADIUS))) + BALL_RADIUS);
}

Ball::Ball(float x, float y) {
  init(x, y);
}

void Ball::init(float x, float y) {
  loc.x = x;
  loc.y = y;

  ball.setPosition(loc.x - BALL_RADIUS, loc.y - BALL_RADIUS);
  ball.setRadius(BALL_RADIUS);
  ball.setFillColor(sf::Color::Red);
  ball.setOutlineColor(sf::Color::Black);
  ball.setOutlineThickness(1);
}
于 2013-02-20T12:56:17.710 回答
3

不允许 C++ 中的构造函数链接,相反,这里将创建一个临时版本的类,而不是在任何地方分配,然后丢弃。

相反,使用您想要的参数创建一个私有初始化方法,并使用正确的参数从您的构造函数中调用它。

于 2013-02-20T12:55:44.747 回答
3

Constructor Chaining is not supported in C++ before C++ 11

You can take the logic to a function and call it from both constructor. something like:

Ball::Ball() {

    // This ugly thing calls the full constructor with a random x and y position
    // in such a way the the entire ball is inside the screen.

   init((rand() % (WINDOW_X - (2 * BALL_RADIUS))) + BALL_RADIUS, (rand() % (WINDOW_Y - (2 * BALL_RADIUS))) + BALL_RADIUS);

}

Ball::Ball(float x, float y) {

    init(x,y);

}

Ball::init(float x, float y) {

    loc.x = x;
    loc.y = y;

    ball.setPosition(loc.x - BALL_RADIUS, loc.y - BALL_RADIUS);
    ball.setRadius(BALL_RADIUS);
    ball.setFillColor(sf::Color::Red);
    ball.setOutlineColor(sf::Color::Black);
    ball.setOutlineThickness(1);

}
于 2013-02-20T13:05:31.907 回答
2

C++ 不支持构造函数链接,除非您使用的是 C++ 11,我认为您不是。

请查看此答案以获取详细信息:

关联

于 2013-02-20T12:55:14.927 回答
1

我建议您不要使用构造函数链接,而是使用两阶段初始化,这意味着您创建一个init()在默认构造函数中调用的函数。

于 2013-02-20T12:56:16.487 回答
1

其他答案给出了语法正确的方法来做到这一点。

我会在语义上做一些正确的事情,以便您这样称呼它:

Ball ball = Ball::createRandom();

createRandom作为以下static功能实现Ball

class Ball {
public:
    //...
    static Ball createRandom();
};

实现为:

int randomisePosition(int position) {
    return (rand() % (position - (2 * BALL_RADIUS))) + BALL_RADIUS;
}

Ball Ball::createRandom() {
    return Ball(randomisePosition(WINDOW_X),
                randomisePosition(WINDOW_Y));
}
于 2013-02-20T13:15:15.883 回答
0

您应该创建一个 init() 方法并在两个构造函数中调用它。

Ball::Ball((rand() % (WINDOW_X - (2 * BALL_RADIUS))) + BALL_RADIUS, (rand() % (WINDOW_Y - (2 * BALL_RADIUS))) + BALL_RADIUS);

创建一个临时球对象并立即销毁它

于 2013-02-20T12:57:49.017 回答