5

まず、答えが明らかな場合は、事前にお詫び申し上げます。私はC++を初めて使用し、母国語はJavaです。Stack Overflowも初めてです。質問に問題がある場合や、他に何か必要な場合は、教えてください。

それで。私はここにこのコードを持っています:(私はベクトルとCircleShapeにSFMLを使用しています)

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);

}

そして、ここにヘッダーがあります(上記のファイルに#含まれています):

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);

すべてが完璧に機能し、ボールが画面に表示されます。私は本当に困惑している人です。誰かが私を助けることができれば、それは素晴らしいことです。

ところで、私はXcode4.5.2でOSX 10.8を実行していて、違いがあればSFMLRC2.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

コンストラクタチェーンは、C++11より前のC++ではサポートされていません。

ロジックを関数に取り、両方のコンストラクターから呼び出すことができます。何かのようなもの:

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 ++ 11を使用していない限り、C++ではサポートされていません。

詳細については、この回答をご覧ください。

リンク

于 2013-02-20T12:55:14.927 に答える
1

コンストラクターチェーンを実行する代わりに、2フェーズの初期化を使用することをお勧めinit()します。これは、デフォルトのコンストラクターで呼び出す関数を作成することを意味します。

于 2013-02-20T12:56:16.487 に答える
1

他の答えは、これを行うための構文的に正しい方法を提供します。

私はあなたがそれをそのように呼ぶように意味的に正しいものを作ります:

Ball ball = Ball::createRandom();

次の関数createRandomとして実装します:staticBall

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 に答える