18

私はこのリンクから知っていstd::enable_shared_from_thisました。 しかし、以下のコードを読んだ後、いつ使用するかわかりません。

try {
        Good not_so_good;
        std::shared_ptr<Good> gp1 = not_so_good.getptr();
    } catch(std::bad_weak_ptr& e) {
        // undefined behavior (until C++17) and std::bad_weak_ptr thrown (since C++17)
        std::cout << e.what() << '\n';    
    }

shared_ptrを呼び出す前に存在しないため、上記のコードは「あまり良くありません」getptr()。したがって、良いことは次のとおりです。

std::shared_ptr<Good> gp1 = std::make_shared<Good>(); // having a shared_ptr at the beginning
std::shared_ptr<Good> gp2 = gp1->getptr();

ただし、既にオブジェクトを持っている場合は、次のshared_ptrように単純にコーディングしてみませんか: std::shared_ptr<Good> gp2 = gp1;、つまり、まったく必要ないということですstd::enable_shared_from_this

私の意見では、二重削除の問題std::enable_shared_from_thisを回避できるように、複数のshared_ptrオブジェクトが同じ制御ブロックを持っていることを確認するために使用します。しかし、最初にa を作成することを思い出さなければならない場合は、生のポインターを使用する代わりに、オブジェクトを使用して新しいオブジェクトを作成することを思い出してください。shared_ptrshared_ptr

4

3 に答える 3

3

std::shared_ptr<T>不透明なポインターのようなテンプレートを使用できないユースケースがいくつかあります。

その場合、これがあると便利です:

some_file.cpp で

struct A : std::enable_shared_from_this<A> {};

extern "C" void f_c(A*);
extern "C" void f_cpp(A* a) {
   std::shared_ptr<A> shared_a = a->shared_from_this();
   // work with operation requires shared_ptr
}

int main()
{
    std::shared_ptr<A> a = std::make_shared<A>();
    f_c(a.get());
}

some_other.c で

struct A;
void f_cpp(struct A* a);
void f_c(struct A* a) {
    f_cpp(a);
}
于 2016-12-28T15:50:50.573 に答える
3

計算ツリーを表現したいとしましょう。式を再帰的に評価できるように、式への 2 つのポインタを持つ式から派生するクラスとして表される加算を使用します。ただし、どこかで評価を終了する必要があるため、数字自体を評価するようにしましょう。

class Number;

class Expression : public std::enable_shared_from_this<Expression>
{
public:
    virtual std::shared_ptr<Number> evaluate() = 0;
    virtual ~Expression() {}
};

class Number : public Expression
{
    int x;
public:
    int value() const { return x; }
    std::shared_ptr<Number> evaluate() override
    {
        return std::static_pointer_cast<Number>(shared_from_this());
    }
    Number(int x) : x(x) {}
};

class Addition : public Expression
{
    std::shared_ptr<Expression> left;
    std::shared_ptr<Expression> right;
public:
    std::shared_ptr<Number> evaluate() override
    {
        int l = left->evaluate()->value();
        int r = right->evaluate()->value();
        return std::make_shared<Number>(l + r);
    }
    Addition(std::shared_ptr<Expression> left, std::shared_ptr<Expression> right) :
        left(left),
        right(right)
    {

    }
};

Live on Coliru

Number::evaluate()withを実装する「明白な」方法はreturn std::shared_ptr<Number>(this);、二重削除になるため、壊れていることに注意してください。

于 2016-12-28T15:51:48.547 に答える