2013-04-19 8 views
8

std :: vectorを返すクラスメソッドを作成しようとしていますが、これを行うための最善の方法について少し混乱しています。 std :: vector - rightアプローチを返す

std::vector<double>* GetBins(void); 

及び方法で

は、私がデータでいっぱいに新しいのstd ::ベクトルを、割り当て:

私が使用したアプローチは、次のメソッドを定義することです。私はこれにポインタを返しています。

std::vector<double>* Frequency::GetBins(void) { 
    std::vector<double> *rtnVec = new std::vector<double>(); 
    for (_itMap = _mapFreq.begin(); _itMap != _mapFreq.end(); _itMap++) { 
     rtnVec->push_back((*_itMap).first); 
    } 
    return rtnVec; 
} 

(_itMapはクラス定義のイテレータです)。私のmain.cppには

、私は次のことをやった:

std::vector<double>* myBins; 
myBins = myFreq3->GetBins(); 
delete myBins; 

私はこのアプローチを知って、私はmain.cppにコード内のポインタを削除しない限り、ダングリングポインタを取得するつもりです、それはすでにちょっと「危険」です。クラスメソッドから新しいstd :: vectorを返す最良の方法は何ですか?

おかげでみんな ピート

+0

なぜ何かを返す必要がありますか? 'BinsProcessor'インターフェースを作成し、あなたの' CustomBinsProcessor'でビンを処理するために 'Frequency'を尋ねます。 –

答えて

15

最良の方法は、値で返すことです:

std::vector<double> Frequency::GetBins() { 
    std::vector<double> rtnVec; 
    rtnVec.reserve(_mapFreq.size()); // reserve enough size, no reallocations 
    for (_itMap = _mapFreq.begin(); _itMap != _mapFreq.end(); ++_itMap) { 
     rtnVec.push_back(_itMap->first); 
    } 
    return rtnVec; 
} 

次に、このような関数を使用したい:

std::vector<double> myBins = myFreq3->GetBins(); 
// no need for delete! 

コンパイラは、おそらく使用しますRVOとコピーを実行しないでください。 C++ 11を使用している場合、移動セマンティクスはコピーが実行されないことを保証します。あなたはコピー/ダングリングポインタ/ ...、別のを避けたい場合は

std::unique_ptr<std::vector<double>> Frequency::GetBins(void) { 
    std::unique_ptr<std::vector<double>> rtnVec(new std::vector<double>()); 

    //... 

    return rtnVec; 
} 
+1

または 'for(auto && elem:_mapFreq){rtnVec.push_back(elem.first); } ' – MSalters

+1

@MSaltersはい、それはマップを反復するより良い方法です。しかし、OPは具体的にはリターンセマンティクスを求めていますが、範囲ベースのforループを使用することで違いはありません。 – mfontanini

+0

公正なポイント。それについて考えると、 'rtnVec.reserve(_mapFreq.size())'も追加します。繰り返しますが、戻り値の型に直接影響することはありませんが、 'rtnVec'を埋めていくうちにいくつかのコピーを取り除いてしまいます。 – MSalters

4

戻ります方法を参考にしてstd::vectorを渡すだけです。

void Frequency::GetBins(std::vector<double>& bins) { 
    for (_itMap = _mapFreq.begin(); _itMap != _mapFreq.end(); _itMap++) { 
     bins->push_back((*_itMap).first); 
    } 
} 

それ以前に定義する:

std::vector<double> myBins; 
myFreq3->GetBins(myBins); 
+0

移動セマンティクスが使用されていない限り、値で戻すとディープコピーが発生します。 – dtech

+3

@ddriver OPの設計とこの記事では、両方とも「RVO」が暗黙的に発生し、コピーエリーションが発信サイトで発生するはずです。 C++ 11では、コードの密接な変種は「RVO」に進むか、暗黙的に「移動する」。 – Yakk

4

std::vector<double> Frequency::GetBins(void) { 
    std::vector<double> rtnVec; 

    // ... 

    return rtnVec; 
} 

しかしあなたは、あなたがスマートポインタを使用することができますポインタで返したい場合は、値によって

関連する問題