8

以下のライブの例を試してみました:

typedef struct point
{
    int x;
    int y;
} point;

void cp(point p)
{
    cout<<p.x<<endl;
    cout<<p.y<<endl;
}

int main()
{
    point p1;
    p1.x=1;
    p1.y=2;
    cp(p1);
}

印刷された結果は次のとおりです。

1
2

それは私が期待したことです。私の質問は次のとおりです。パラメータpはオブジェクトp1の完全なコピーを取得しますか?もしそうなら、これは良い習慣かどうか疑問に思いますか?(構造体のサイズが大きくなると、コピーのオーバーヘッドが大きくなると思いました)。

4

6 に答える 6

18

はい、これには何の問題もありません。はい、pの完全なコピーですp1struct私は2つintのsを大きくして呼び出すことはしませんが、structが大きくなり、関数本体で変更する必要がない場合は、const参照で渡すことを検討できます。

void cp(const point& p)
{
    // ...
}
于 2010-04-27T20:14:16.007 に答える
8

構造体をパラメータとして渡すことには何の問題もありません。すべてがC++で値によって渡されるため、完全なコピーが実際に作成されます。

例で示した構造体は小さいので、値で渡しても問題はないでしょう。ただし、より大きなデータ構造で作業する場合は、参照によって渡すことをお勧めします。

ただし、参照渡しとは、関数内の構造体を変更すると、元の構造体が変更されることを意味することに注意してください。構造体を変更しない場合は、必ずconstキーワードを使用してください。これにより、関数が情報を変更するかどうかについての情報がすぐに得られます。

あなたの例は、このように参照を処理するように変更できます:

typedef struct point
{
    int x;
    int y;
} point;

void cp(const point& p) // You can know that cp doesn't modify your struct
{
    cout<<p.x<<endl;
    cout<<p.y<<endl;
}

void mod_point(point& p) // You can know that mod_points modifies your struct
{
    p.x += 1;
    p.y += 1;
}

int main()
{
    point p1;
    p1.x=1;
    p1.y=2;
    cp(p1);
    mod_point(p1);
    cp(p1); // will output 2 and 3
}
于 2010-04-27T20:25:49.617 に答える
6

あなたの質問に答える前に(この投稿の最後にあります)、関数に引数を渡すための可能性の簡単な要約を次に示します。


1.コピー構築されたオブジェクト(値渡し):

void cp(point p);

これは値渡しです。一時オブジェクトは、渡したオブジェクトpointから作成およびコピー構築されます。実行が関数を離れると、一時オブジェクトは破棄されます。pointcpcp

関数は関数に渡されたもののコピーを操作するため、そのローカルpointオブジェクトを必要なだけ変更でき、呼び出し元の元のオブジェクトは影響を受けないことに注意してください。値渡しパラメーターを使用してこの動作を変更する方法はありません。


2.オブジェクトへの参照(参照渡し):

void cp(point& p);

これは参照渡しです。関数に渡された実際のオブジェクトは、関数内で使用可能です(変更される可能性があります)。関数が渡されたオブジェクトを変更できないようにする場合は、パラメーターを次のように宣言しますconst point&

void cp(const point& p);

3.オブジェクトへのポインタ(参照渡し):

void cp(point* p);

これも参照渡しですが、いくつかの微妙な違いがあります。注目すべき違いの1つは、関数にnullポインターを渡すことができることです。参照は初期化する必要があり、後で再装着できないため、これは参照では不可能です。cp-参照と同様に、渡されたものの変更を禁止pointする場合は、constとして宣言します。

void cp(const point* p);

あなたの質問への答え:

値渡しパラメーターは、本質的に悪いものではありません。もちろん、コピーの作成に費用がかかるタイプ(たとえば、非常に大きいオブジェクトや複雑なオブジェクト)や、特定の副作用があるタイプ(たとえば、std::auto_ptr)もあります。このような場合は注意が必要です。それ以外の場合、これはC ++のもう1つの機能であり、完全に合理的な用途があります。

于 2010-04-27T20:24:40.997 に答える
1
void cp(point p){
}

値で取得

void cp(point *p){
}

参照により取得

他のデータ変数と同じように。

Javaではシナリオが異なります。渡すオブジェクトは常に参照によって移動します。

于 2010-04-27T20:15:44.663 に答える
1

この場合、ポイント構造体は「値で」渡されます。これは、構造体全体がコピーされることを意味します。ビッグデータタイプの場合、これは確かに遅くなる可能性があります。

参照によってオブジェクトを渡すことを検討できます

void cp(point& p) // p may be altered!

またはconstリファレンスになる

void cp(const point& p) // p may not be altered!
于 2010-04-27T20:15:48.800 に答える
1

オブジェクトを値で渡さないようにする可能性を確認してください。オブジェクトは単に「コピー」されるだけでなく、コピーで構築されます。したがって、これには、オブジェクトがより多くのオブジェクトで構成または派生している場合に、コピーコンストラクターとコピーコンストラクターのチェーンを呼び出すことが含まれます。可能であれば、参照を渡します。

void cp(point&p const)const {

    cout << p.x << endl;
    cout << p.y << endl;

}

于 2010-04-27T20:17:15.023 に答える