2012-03-19 4 views
-3

私はdouble*を返すメソッドを書いています。しかし、私は、このメソッドの出力に別のメソッドの振る舞いを基にしたいと思います。私はそれがその後、「初期化」または「ビルド」double*とのいずれかを返すmethodReturningArray()を持っていることが適切であるC++ - ポインタをテストする

if (methodReturningArray()==0) 
{ 
    this_behavior(); 
} 
else 
{ 
    this_other_behavior(methodReturningArray()); 
} 

を持っているしたいと思い、このdouble*が適切にその

double* new_array ; 
return new_array ; 
のように戻って、初期化または構築することできなかった場合

つまり、double*の出力は、double*の出力を構築できるようにいくつかのプロパティが完了しているかどうかを確認するブール値の役割も果たします。

ありがとうございます。

+4

、できた誰*ポイント*私はそれに? – Griwes

+0

それは... [?]、忘れる? 。言い訳。 – octoback

+0

あなたが何を求めているのかわかりません。あなたの質問は奇妙に言われており、私たちはあなたが何を援助したいか分からない。あなたはそれを言い換えることができますか? – user1118321

答えて

1

ポインタで返されたものが初期化されていないことを示すには、return NULLを使用します。 if(double* d = method())(または好きな方法で)をチェックしてください。

しかし、これはあなたの(または私の)祖父のC++ではないので、絶対にそうする理由があるときは、このような文章を書いてください。 std::arrayまたはstd::vectorの値を折り返して返し、初期化の失敗につながる動作が何となく例外的な場合は例外をスローすることをお勧めします。初期化に失敗した場合は、戻り値をboost::optionalにラップします。しかし、おそらく私はOutputIteratorがクライアントに特定のコンテナを強制しないものを書くだろう。

災害に関する注意:double* d; return dは、クライアントにランダムなメモリを指すポインタを残します。彼女がdeleted[]であるかどうか、またはそれが有効であるかどうかを判断する方法はありません。常にポインターを初期化してください。

コードスニペット:私はここにすべての質問を参照することはできません

// outputiterator 
template<typename OutputIterator> 
void myFunc(OutputIterator o) { 
    // fill stuff in 
    if(someThing) { 
    for(int i = 0; i < 5; ++i) 
    { 
     *o++ = 23; 
    } 
    } else { 
    // leave it empty 
    } 
} 

// client calls like: 
std::vector<double> v; 
myFunc(std::back_inserter(v)); 
if(!v.empty()) { 

} else { 

} 

// exception 
std::vector<double> myFunc() { 
    std::vector<double> v; 
    if(someThing) { v.push_back(23); return v; } 
    else throw std::runtime_error("Nargh!"); 
} 

// client 
try { 
    auto v = myFunc(); 
} catch(std::runtime_error err) { 

} 

// optional 
boost::optional<std::vector<double>> 
myFunc() { 
    std::vector<double> v; 
    if(someThing) { v.push_back(23); return v; } 
    else return boost::optional< std::vector<double> >(); 
} 

//client 
auto v = myFunc(); 
if(v) { 

} else { 

} 
+0

私は同意しません。そのような場合には愚かなラッパーやBoostを使う理由は全くありません。コードを畳み込むだけで、より詳細にテンプレート化することで、より冗長でコンパイルが遅くなります(特にテンプレート処理に関しては正確ではないgccの下で)。またはEHでさえ、巻き戻し時に無駄なランタイムと黒い魔法を追加するだけです。 – q66

+1

@ q66 'optional'は、あなたのコンパイル時間をあまりにも傷つけるものではなく、あまり冗長ではありません。私は他人の 'new'を'削除する 'ことを好まず、そのように書かれたものでアロケータを変更する必要があるとすぐに問題に陥ることを望みます。しかし、その議論は実際には長すぎて十分な頻度で考えられてきました。両面にメリットがあり、それはあなたの目標の問題です。 – pmr

+0

実際には、Boostが相互依存関係に詰め込まれているため、ほぼすべてのBoostコンポーネントを含めてコンパイル時間が犠牲になるため、多くのコードを拡張する必要があります。私は本当にこれが本当の利益だとは思わない。削除に関しては、大部分のケースで問題ありません。手動での処理がエラーを起こしやすいような場合には、refcountingの使用方法がわかりますが、それはまれです。 – q66

0

基本的に3つの方法があります。

1)エラーの場合は、NULLを返します。その後、ブールチェックを問題なく実行できます。ほとんどの場合、十分です。

2)戻りブール値、及びこのような参照またはポインタ引数を使用して二重*出力処理:

bool methodReturningArray(double **out) { *out = ...; return true; } 

double *out; 
if (!methodReturningArray(&out)) this_other_behavior(out); else .... 

3)例外スロー - IMOちょっと入り組んだと役に立たないし。

初期化されていないポインタを返すと、ブール値の評価はできません。そのポインタは後でポインタがぶら下がると想定されるため、危険です。

+0

私は実際にこのような状況を処理するために、C++でより良いイディオムがあると考えています( 'boost :: optional'、値渡し)。 – pmr

+0

@ pmr、私は本当にそうは思わない、それを行うことに事実上メリットがない、と私はいくつかの欠点を考えることができます。私は「現代的な」C++スタイルが本当に好きではなく、IMOは絶対に何も理由がないので、物事を過度に複雑にします。 – q66

+0

"理由がない"と思われる場合は、ここの「配列と文字列の処理」カテゴリのバグを見てください:http://www.viva64.com/en/a/0079/ *それらのすべては、 "現代的"なC++スタイルを使用しないことによって引き起こされます。個人的には、私はこの恥ずかしさを感じます:プログラマーたちは、今日も30年前もまだ間違いを犯しています。このコードのユーザーは、ポインタが指している配列のサイズをどのように知っていますか?あなたはあなたが好きではないと主張することができ、あなたが望むすべてを必要としないが、それは「理由なし」であると主張することはできない。 –