2016-04-08 15 views
1

2つのベクトルを作成し、それらを関数に渡し、関数がリストのデータを変更しないことを保証するコードを以下に示します。可能な場所は**const**と記されています。もし私がお見逃ししたら、私に知らせてください。基本的に私は、賛否両論の面でそれぞれの面で正しい考えがあるのか​​、どちらを使うべきかを知りたいと思っています。関数宣言でConstを使うことの長所と短所

#include <iostream> 
#include <vector> 

using namespace std; 

int makeSum(/**/ const /**/ vector<int>& lst) /**/ const /**/ 
{ 
    int total {}; 

    lst.push_back(1); 

    for (/**/ const /**/ auto& value : lst) { 
     total += value; 
    } 

    return total; 
} 

int main(int argc, char* argv[]) 
{ 
    vector<int> test1 = {1, 2, 3, 4, 5}; 
    vector<int> test2 = {2, 3, 5, 6}; 

    cout << makeSum(test1) << endl; //15 
    cout << makeSum(test2) << endl; //16 

    return 0; 
} 
  • パラメータリスト内のConst:これはCONSTまたは非constベクトル変数のいずれかが、この関数に渡すことができるようになります。しかし、変数名lstはconst変数を参照しているため、変数にconst_castが使用されていない限り、ベクトルのデータメンバーを変更することはできません。

  • Const関数宣言の後に:これはメンバー関数である必要がありますが、メンバーの変更は許可されません。

  • Constに基づく範囲ループ:これは、関数が非constパラメータのみを受け入れるようにしますが、範囲ループが参照を変更しないことを保証します。

+0

私は第2の箇条書きでそれを述べました。 –

+2

定数参照を渡すことについて忘れた場合:非定数参照は、一時オブジェクトまたはリテラル/定数値にバインドできません。 –

答えて

1
  • パラメータリスト内のConst:これはCONSTまたは非constベクトル変数のいずれかが、この関数に渡すことができるようになります。しかし、変数名lstはconst変数を参照しているため、const_castが変数に使用されていない限り、ベクトルのデータメンバーを変更することはできません。

「のconstまたは非constのいずれか...これができるようになる」、後者についてハズレは限り、あなたはその関数の内部でそれを変更するつもりです。

  • のConst関数宣言の後:これはメンバ関数があったことを必要とするであろうが、任意のメンバを変更することを許可しないであろう。

あなたは実際にメンバー機能を持っていません。 Const範囲ベースのforループで

  • :これは非constパラメータを受け入れるように機能を強制だろうが、レンジループが基準を変化させなかったことを確実にします。

"...しかし、範囲ループは、基準を変化させなかったことを確実にするでしょう" もちろん

を。いくつかの理由


Your code doesn't compile

lst.push_back(1); 

const基準パラメータに適用される非const動作です。

int makeSum(/**/ const /**/ vector<int>& lst) /**/ const /**/ 
               // ^^^^^ 

は、自由な機能には意味がありません。 constポストフィックスは、クラスのconst(rvalue)インスタンスで使用できるクラスメンバ関数に使用されます。


上記のコードでは、技術的なエラーについて説明しています。 constを使う賛否両論に関しては、私が言うことができる唯一のことは次のとおりです:

  • 最初から正しく使用してください。
  • これを使用して、コードの意図したセマンティクスを表現します。

これはプロ側のもので、無効なコードに対してより堅牢なものにしています。

const宣言を正しく取得するために、より大きい既存のコードベースをリファクタリングする必要がある場合は、詐欺側が出てくる可能性があります。これは重大なPITAになる可能性があり、それが価値がある場合は再考すべきです(特に既に動作しているコードの場合)。

+0

私はコードがコンパイルされることを意図していたとは思わない、単に例だった。 'const'クラスの関数を単純なクラスにネストして、このコンクリートを作るべきであることを許可しました。 –

+0

@NowhereMan _「コードはコンパイルされていないと思います」_私はそうでもないと思っていました。 –

0

私も一つのことを明確に最初の作りたかった:

...はconst_castを変数に使用されていない限り。あなたは決してこのことを心配し、あなたcertaintlyは、このようなキャストのために対応するためにコードを書くべきではないはずです

const_castは本質的に危険です。 constと宣言した場合、なぜ地球上でその一定性を試して除去しようとしますか?彼らは明らかにキャストが機能するかもしれないいくつかのケースですが、何かを宣言しなければならないかどうかを判断する際に、あなたの懸念事項ではない、まれにしかありません。ここで

は私が可能-whenever constメンバfuntionsにconst

  • をキーワードを使用することを決定、への意図しない変更を防止するために、これを行うには良い方法である際に従ういくつかのガイドラインですクラスのメンバー。その機能がconstであることがわかっている場合は、メンバー変数は変更されません。

  • のconst関数は

    -thisはあなたが過負荷に紹介する場合は特に、この質問の範囲を超えての方法ですPARAMATERS、しかし、私はあなたにいくつかの非常に基本的なヒントを与えるだろう。

    -use const実際に関数内でそのコピーされた値を変更する必要がない場合。一例は積分値であり、ほとんど常に値によって渡される。あなたが持っている場合は、たとえばconst int xのために決してしてxが作る変更それconst参照あなたはconst値によって、あなたが参照によってを渡すことになる唯一の違いオブジェクトを使用するのと同じ方法によって

    -use constことベクターのようにコピーするのが高価です。

  • constの範囲-用ループ

    あなただけそれを読んで、オブジェクトを変更していないconst -use。

経験則です。オブジェクトが変更されないことが確かな場合はいつでもconstを使用してください。完全にわからない場合は、使用しないでください。それは本当に簡単です。これが助けて欲しい!

関連する問題