4

実際のポインターを使用するのと同じように、shared_ptr を使用したいと考えています。みたいなことができるようになりたかった

shared_ptr<int> a;
a = new int(5);
a = 0;
shared_ptr<int> foo()
    return 0;

ただし、デフォルトでは実装されていません。

boost ライブラリの shared_ptr のソース コードを次のように変更しました。

template<class Y> void operator=( int i )
{
    reset(i);
}
template<class Y> void reset(int i)
{
    this_type(i).swap(*this);
}
template<class Y> void operator=( Y * p )
{
    reset(p);
}
shared_ptr(int i): px(0), pn()
{
}

唯一のことは、私が a = -1; を行う場合です。通常は整数値をポインターに割り当てることができないため、コンパイルして null ポインターが返されますが、これは問題にはなりません。

私の質問は、これを実装する正しい方法ですか、それともアプリケーションをクラッシュさせる可能性のあるケースを忘れてしまったのでしょうか? どこを見ても、shared_ptr の nullpointer を取得する唯一の方法は、ptr = 0; と比較してコードがあまり洗練されていないデフォルトのコンストラクターを呼び出すことでした。

4

2 に答える 2

26

いいえ。ソースを変更しないでください。それには理由があり、非常に賢い人々は、編集するよりも定義方法の方が優れていると判断しました。

あなたが持っているものは意味さえありません。整数をポインターに割り当てることはできません。これらは 2 つの異なる型ですが、そのようなセマンティクスを与えています。あなたは言う:「...通常は整数値をポインターに割り当てることができないため、これは問題にならないはずです」が、質問の上部で「私と同じようにshared_ptrを使用したい」とも言いました実際のポインタを使用してください。」さて、それはどれですか?整数をポインターに割り当てて null に設定することは、取得できる実際のポインターとはかけ離れているためです。

一歩下がって、自分が望んでいることは常に最善であるとは限らないことを理解する必要があります。これらの変更を元に戻し、クラスを適切に使用する必要があります。私は意地悪になりたくありませんが、これは真剣にあなたが行きたいルートではありません。それは危険であり、無意味なセマンティクスを持ち、保守が不可能です。

于 2012-04-22T08:14:17.380 に答える
10

shared_ptr はポインターのようなインターフェースを実装しているため、*and->演算子を使用できます。

デフォルトで構築された (空の) shared_ptr は、内部的にはnullptrと等しいため、明示的に割り当てることについて心配する必要はありません。すなわち

std::shared_ptr<int> sh;
std::cout << ( sh.get() == nullptr ) << std::endl;

// Or alternatively:
std::cout << ( sh == nullptr ) << std::endl;

また、(私の意見では) shared_ptr を使用してオブジェクトを作成する最もエレガントな方法はstd::make_shared関数です。これには、 "we know where you live idiom"として知られる内部最適化により、一部のコンパイラ (少なくとも MSVC++) でわずかに効率が向上するという追加の利点もあります。

#include <memory>
#include <string>

class foo
{
public:
    foo(std::string s, int n) {}
};

int main()
{
    auto p = std::make_shared<int>();
    auto q = std::make_shared<foo>("hello", 2);
}
于 2012-04-22T08:15:01.470 に答える