2017-05-15 8 views
1

は、私はそのC++ - リターンC++ 11のstd ::配列

#define SIZE 10 
Class User 
{ 
public: 
    std::array<Account, SIZE> getListAccount() 
    { 
     return listAccount; 
    } 
private: 
    std::array<Account, SIZE> listAccount 
} 

Class Account 
{ 
public: 
    void setUserName(std::string newUSN) 
    { 
     userName=newUSN; 
    } 
private: 
    string userName; 
    string password; 
} 


int main() 
{ 
    User xxx(.......); 
    xxx.getListAccount()[1].setUserName("abc"); // It doesn't effect 
    return 0; 
} 

のようないくつかのコードを持っていないのはなぜ主な変更でsetUserName()関数呼び出し私のxxxユーザーで名前は?ところで

  • 私は私の実際のコードでは、バイナリファイル
  • にデータを保存したいので、私はstd::arrayを使用しています、私のユーザーのchar []、文字列ではありません
+5

getterは配列のコピーを返します。したがって、名前はコピーで変更され、オリジナルでは変更されません。 –

+0

具体的な質問をする必要があります。処方から、あなたが本当に望むものが明確でないことがあります。ほとんどの場合、配列または配列への参照を返す必要はありません。 – bobah

+2

無効なC++コードをペーストした: 'class'はすべて小文字でなければならず、' std :: array 'で使用する前に' class Account'を定義する必要があります。 - [mcve]を提供する方法をお読みください!また、名前の汚染を少なくするために、 '#define'を使わないでください。代わりに 'static const size_t SIZE = 10;'または 'enum {SIZE = 10};を宣言してください(両方とも使用したいクラス内で行うこともできます)。 – chtz

答えて

5

リストへの参照を返す代わりに

std::array<Account, SIZE> & // << Note the & 
User::getListAccount(); 

またはそれ以上の場合、内部stを公開しないでくださいructure

Account& 
User::getUser(size_t n) 
{ 
    return listAccount[n]; 
} 
+2

多くの理由から、エンティティの隙間をインターフェイスに公開することは、通常はあまり良いアイデアではありません。 – bobah

+0

ユーザーがインデックスを使用してアカウント機能を複製することも可能です。私には、getUserのアプローチと比較して明らかな勝者はありません。あまりにも多くの重複は、あまりにも多くのゲッターも乱雑になることができます。 – stefaanv

0
std::array<Account, SIZE> getListAccount() const { 
    return listAccount; 
} 

が、これは、アレイのコピーを返します。

std::array<Account, SIZE>& getListAccount() { 
    return listAccount; 
} 
std::array<Account, SIZE> const& getListAccount() const { 
    return listAccount; 
} 

これは配列への参照を返します。

template<class T> 
struct span_t { 
    T* b = 0; T* e = 0; 
    span_t()=default; 
    span_t(T* s, T* f):b(s),e(f){} 
    span_t(T* s, std::size_t l):span_t(s, s+l){} 
    T* begin() const{ return b; } 
    T* end() const{ return e; } 
    T& operator[](std::size_t i)const{ return begin()[i]; } 
    std::size_t size() const { return end()-begin(); } 
    bool empty() const { return begin()==end(); } 
}; 

span_t<Account> getListAccount() { 
    return {listAccount.data(), listAccount.size()}; 
} 
span_t<const Account> getListAccount() const { 
    return {listAccount.data(), listAccount.size()}; 
} 

これはアカウントを格納するために使用される基礎となるデータ構造を晒すことなくアカウントの連続した範囲を表すポインタの一対のラッパーを返します。

これら3つのうち、span_tを使用します。オーバーヘッドがゼロになり、クライアントが関心のない情報が隠されます。

関連する問題