2011-08-04 11 views
7

私はC++には比較的新しいので、私の質問は例で分かりやすいと思います。 copyVar1メソッドを実装するときに、私のヘッダファイルでは、私は私の実装の.ccファイルで 実装ファイルのC++ゲッターセッター

class myClass{ 
    public: 
     double getVar1(); 
     void setVar1(double newVar1); 
     void copyVar1(myClass* dat); 

    private: 
     double var1; 
}; 

があると、私はやるべき

void myClass::copyVar1(myClass* dat){ 
    var1 = dat->var1; 
} 

または

void myClass::copyVar1(myClass* dat){ 
    var1 = dat->getVar1(); 
} 

秒で私は代わりにゲッターメソッドを使用します。どちらもVisual C++で正常に動作しますが、どちらが実際に使用する方が良いかを知りたいと思います。

ご意見ありがとうございました!

+1

[C++プログラマで一般的な関数の取得と設定](http://stackoverflow.com/questions/737409/are-get-and-set-functions-popular-with-c-programmers) –

答えて

4

ベストプラクティス?メソッドを記述するのではなく、代入演算子をオーバーロードします。

myClass & myClass::operator=(const myClass & dat) 
{ 
    var1 = dat.var1; // or dat.getVar1() 
    return *this; 
} 

フィールドを使用したり、セッターを呼び出して...それはすべて個人的な味の問題です。あなたのゲッターに副作用がある場合は、それを呼び出す必要があります。それ以外の場合は、フィールドを使用します。

だから、大きな "依存する"。

+1

クラスに複数のメンバーが含まれていると、1つではなく、すべての値をコピーする必要があるため、割り当ては機能しません。 – Skizz

+0

@Skizz実際、この例ではフィールドが1つしかありません。 –

+1

* getter *を使用すると、操作が1か所に集約されます。これは保守とデバッグの利点です。コンパイラは、ゲッターをインライン化するのに十分なほどスマートでなければなりません。それ以外の場合はgetterとsettersをインラインにして、コンパイラの最適化を助けます。 –

0

によって異なります。変数の代わりにゲッター/セッターを使用することは、プログラミングのエラーや変更に対してより堅牢であり、コードの重複を減らすことを多くの人があなたに伝えます。しかし、これらのgetter/setterがインライン関数でない限り、パフォーマンスの低下が少なく、インプリメンテーションがクラスの内部を知る必要があるため、変数を直接使用するだけではいかがですか。

1

いくつかの実装の詳細(例えば値アサインの検証を紹介)あなたは冗談がセッター内の1つの場所でそれを変更する必要がある方法あなたの変更を場合、私はセッターを使用して好むとその方法をゲッタリングでしょう...

+0

getterには、一致するメンバー変数がないのに、代わりに何らかの形で計算されることがあります。そのような状況では、明らかに変数を直接使用する必要があります。究極の答えはありませんimho:変数/ゲッターが表すものに依存します。 – ereOn

+0

@ereOn - はいそれは依存しています... –

0

あなたがしようとしていますコピーコンストラクタを書くには?なぜあなたはsetVar1を持っているときにcopyVar1が必要ですか?コピーコンストラクタを作成しようとしている場合は、getterを使用しない方が良いでしょう。あなたはゲッターとセッターの両方を持っている場合は、なぜvar1がパブリックにしない

myclass(const myclass& other) 
{ 
var1 = other.var1; 
} 

+0

代入の代わりにコンストラクタでイニシャライザリストを使用する方が良いです。 –

+0

これは単なる例です。私が現在実装しているcopyVar1メソッドにはさらに多くのものがあります。 –

+0

@ A-A:あなたが望むのは、**コピーアサイン**です。 'myclass&operator =(const myclass&other);' @Etienneの解決策を見てください。 – Mahesh

2

クラスの外にいるときには、ほとんどの場合getter/setterメソッドを使用して変数にアクセスする必要があります。そうしなければならないため、しばしば行う必要があります。しかし、あなたがクラスの中にいるときにはどちらかを使うことができ、getterメソッドが何もせずに変数を返すならば、それは違いはありません。

あなたはcopyVar1が呼び出されたときにそのコードが実行されるようにしたい場合は、ゲッターだけ変数を返すよりも何かをする方法、およびのコードを持っている場合あなたの決定が基づくことになるだろう。あなたがわからない場合、私のアドバイスは、のコードを将来変更することを決定した場合でも、getterメソッドを使用することです。今すぐ直接アクセスするだけで正常に機能し、微視的にはパフォーマンスが向上するかもしれませんが、必要なときにゲッターを呼び出さないでください。そして、コンパイラはおそらくあなたがその違いを感じさせないほどに最適化を終わらせるでしょう。 :D

+1

ほとんどのコンパイラはゲッターをインライン展開するため、ここではパフォーマンスは問題になりません。 –

0

ここでそれを行う方法はありません。

ただし、getVar1()が値またはvar1を返すと仮定しています。 var1値の格納方法を変更する場合は、すべてのコードを調べて更新する必要があります。 setter/getterを使用すると、これはほんの数通りの方法になります。その場合、あなたは番目のオプションを使用する必要があります

void myClass::copyVar1(myClass* dat){ 
    setVar1 (dat->getVar1()); 
} 

をして、あなたは完全にVAR1への依存を削除するには、何か他のものにVAR1を変更することができますし、copyVar1はまだ動作します。

0

あなたが言うように、両方とも正しく動作し、完全に合法です。

メンバー変数に直接アクセスすることとアクセサーを使用することの違いは、クラス内でより強力な「レイヤー」を定義することです。このレイヤは、任意のレイヤとして、依存関係を減らすのに役立ちます。

つまり、ゲッターメソッドは、基本的に実装の詳細を外部に公開しないという要件に応答します。たとえば、var1を二重に保存する代わりに、計算することもできます。したがって、アクセサはあなたにこの種の自由を与えます。ある程度、他のクラスに影響を与えずに(つまり、依存関係を減らして)実装を変更することができます。

getterメソッドをクラス自体で使用する場合、つまりクラススコープ内の依存関係を削除する場合も同じことが当てはまります。そのため、デザインは変更に対してより復元力があります。

0

セッターとゲッターの抽象化のポイントは、検索の方法が変わる可能性があるということです。メンバー変数に直接アクセスすると、何か変更があった場合は、どこでも使用状況を更新する必要があります。しかし、関数を使用する場合は、変数の取り込み方法を変更するだけで関数を変更する必要があります。

これは同じクラスなので、変数をパブリックにするよりも、この1つの実装ファイルを更新するだけで済みます(クラスのすべてのユーザーを更新する必要がないため)ライブラリクラスをお持ちの場合は可能です)。

これを見るには、突然スレッドセーフにしなければならないクラスを見てください。さて、あなたのコピー機は、

のようになります。あなたはいつも関数で呼び出すと、他の場所に固定する必要はありません。あなたはエンジニアが他の人のオブジェクトをロックすることを忘れないように持たせる場合は、直接変数にアクセスした場合、それがDATに外部の「DAT」のミューテックスをロックし

void myClass::copyVar1(myClass * dat) 
{ 
    scoped_lock lock(mutex); 
    scoped_lock lock2(dat->mutex) 
    var1 = dat->var1; 
} 

ようになり、通常は(非常に良いデザインとは見なされません彼らは忘れるチャンスを開き、それをしないでください)。

同様に、変数がデータベースに格納され始めた場合は、同様にそれを処理する必要があります。あるいは、変数が2つの異なる変数に格納され、検索されたときに構築された場合、複雑さがどのように増加するかを見ることができます。

しかし、アクセサとミューテータを使用する設計思想は、カプセル化によって潜在的な複雑さを減らすことです。クラスを変更しようとする意図がない小規模なプロジェクト(特に個人的なプロジェクト)に取り組むときがあります。それらに直接アクセスすることはそれほど複雑ではないかもしれません。そうすることを恐れてはいけません。あなたがなぜ決定を下すのかを知ってください。

+0

また、コピーコンストラクタや代入演算子は、ミューテータと同じものには使用しないでください - 異なる場所で使用する必要があります。コピーと割り当ては、あなたが望むものとまったく同じような別のオブジェクトを持っている場合に使用されます。ミューテータは、オブジェクトの残りの部分を変更することなく、動作を特定の方法で変更できるようにする場合に使用されます。変更されない状態が他にある場合にのみ、ミューテータを作成します。ミューテータの形式(別の既存のオブジェクトから状態を取得する)は、それが割り当てまたはコピーでなければならないことを意味してはいけません。 – ex0du5