0

これはおそらく簡単なことですが、私は少し困惑しています。ベクトルがうまく動作しないという問題がありましたが、今では原因が見つかったようです。これが私のPlayerクラスの骨抜きバージョンです。

class Player {
private:
    std::string _firstName;
    std::string _lastName;
public:
    Player(std::string firstName, std::string lastName) {
        _firstName = firstName;
        _lastName = lastName;
    };
    Player(const Player& otherPlayer) {
        _firstName = otherPlayer._firstName.c_str();
        _lastName = otherPlayer._lastName.c_str();
        std::cout << "Created " << _firstName << " " << _lastName << std::endl; // Why doesn't _firstName and _lastName contain anything?
    };
    std::string GetName() { return _firstName + " " + _lastName; };
};

int main(int argc, const char * argv[])
{

    Player player1 = Player("Bill", "Clinton");
    Player player2 = Player(player1);

    std::cout << "Player: " << player2.GetName() << std::endl;

    return 0;
}

出力はわずかPlayer:です。特にこのようなアドバイスに照らして、私のコピー コンストラクターが自分のやりたいことを実行しない理由がわかりません(ザック ハウランドのコメントが - の部分を説明していc_str();ます)。私は 3 のルールに違反していますか (ところで、まだ完全には理解できていません)。誰かが私を正しい方向に向けることができれば、本当に感謝しています!

4

1 に答える 1

4

それは私のために働く:http://ideone.com/aenViu

追加しました:

#include <iostream>
#include <string>

しかし、私が理解できないことがあります:

_firstName = otherPlayer._firstName.c_str();
_lastName = otherPlayer._lastName.c_str();

なぜ.c_str()ですか?を変換しstringて新しい?char*に割り当てます。string

EDIT :コメントから、Zac Howland は次のように指摘しましたc_str()。標準はそれを排除しますが、彼が古いコンパイラを使用している場合、または C++11 をまだ完全に実装していないコンパイラを使用している場合は、ディープ コピーが保証されます。」

ただ行う:

_firstName = otherPlayer._firstName;
_lastName = otherPlayer._lastName;

そして、このコピーコンストラクターが本当に必要ですか? デフォルトはあなたが望むことをするでしょう...


また、メンバーを割り当てる代わりに:

Player(std::string firstName, std::string lastName) {
    _firstName = firstName;
    _lastName = lastName;
}

代わりにmember-initialization-listを使用してください:

Player(std::string firstName, std::string lastName) :
    _firstName( std::move(firstName) ),
    _lastName( std::move(lastName) )
{}

最初のケースでは、文字列のデフォルト コンストラクターが呼び出され、次に文字列のコピー代入演算子が呼び出されます。コピー コンストラクターを直接呼び出す 2 番目のケースと比較して、確実に (マイナーな) 効率の低下が生じる可能性があります。

最後に、可能であれば、メソッドの引数として値を渡さず、変更する必要がない場合は参照や const 参照を渡します。

Player( const std::string& firstName, const std::string& lastName )
//      ^^^^^            ^            ^^^^^            ^
    : _firstName( firstName )  // no move here, since args are constant references
    , _lastName( lastName )
{}

すべての変更の実際の動作例。

于 2013-08-21T20:44:23.717 に答える