4

前提条件: この質問を理解するには、最初に次の質問とその回答を読んでください 。auto_ptr<Base>をauto_ptr<Derived>にキャストします。

キャストで auto_ptr<Base>からauto_ptr<Derived>に、Steveは「static_castはauto_ptrを一時的なものにコピーするため、aSがリセットされ、一時的なものが(ステートメントの最後に)あるときにリソースが破棄されると答えました。 「」

static_castと呼ばれている間の一時的な作成のプロセスに興味があります。この効果を確認するために、トレースできるコードが必要です。static_cast<auto_ptr<Circle>> ...コンパイルできないので使えないので、代わりにシミュレーションクラスを書いて、一時的な作成の過程を見る必要がありますauto_ptr

また、一時的な作成はコピーコンストラクターの呼び出しと密接に関連していることも理解しています。 の所有権の喪失は、ソースのフィールドを負の値にauto_ptr設定するコピー割り当てでシミュレートされます(の単純な論理モデルが必要です)。_radiusauto_ptr

したがって、次のCircleクラスをお勧めします。

#include <iostream>

class Shape {};

class Circle: public Shape {
  double _radius;
public:
  explicit Circle(double radius = .5): _radius(radius) {}
  Circle &operator =(Circle &circle) {
    _radius = circle._radius;
    circle._radius = -1.;
    return *this;
  }
  Circle(Circle &circle) { *this = circle; }
  double GetRadius() { return _radius; }
};

int wmain() {
  using namespace std;

  Circle c1(100), c2(200), c3(300);
  c2 = c3;

  Shape *s1, s2;
  s1 = &c1;
  wcout << static_cast<Circle *>(s1)->GetRadius() << endl;

  return 0;
}

Ok。ここでは、「所有権の譲渡」がで行われていることがわかりますc2 = c3。しかし、で一時的な作成を行うことはできませんstatic_cast

問題は、一時オブジェクトの作成の小さなシミュレーションをどのように作成するstatic_castかです。

スティーブは、キャスト中に一時的なオブジェクトが作成されると信じています。私が欲しいのは、一時的な作成を示す例を書くことだけです。このターゲットには学術的な理由があります。

誰かが、参照されたトピックに投稿したスティーブの回答に記載されている効果を達成する方法を明確にすることができますか?

4

4 に答える 4

3

前の質問でauto_ptrは、所有権を持つクラスであり、コピー時にソースのポインターを null にリセットします。

現在Circleは、コピー時に半径を -1 にリセットすることで、所有権をシミュレートするクラスです。そういうauto_ptr意味ではそうですが、他の方法ではそうではありません。

したがって、シミュレートされた所有権の喪失を観察するには、 a をコピーする必要がありますCircle。これは、行のコピー割り当てで行うことですc2 = c3。a をキャストしCircle*てもオブジェクトはコピーされず、ポインターだけがコピーされますが、 a をキャストするCircleとオブジェクトがコピーされます。

int main() {
    Circle c1(100);
    static_cast<Circle>(c1);
    std::cout << c1.GetRadius() << '\n';
}

出力は -1 です。

または、派生クラスへのキャストで特に表示したい場合は、次のようにします。

struct SpecialCircle: Circle {
    SpecialCircle(Circle &circle) : Circle(circle) {}
    explicit SpecialCircle(double radius = .5): Circle(radius) {}
};

int main() {
    SpecialCircle s1(100);
    Circle &c1 = s1;
    static_cast<SpecialCircle>(c1);
    std::cout << c1.GetRadius() << '\n';
}
于 2011-12-21T10:01:03.270 に答える
1

Ok。ここでは、c2 = c3 で「所有権移転」が行われていることがわかります。しかし、私は一時的な作成を達成できませんstatic_cast

static_cast<Circle> (c2); 

から「盗みます」c2

于 2011-12-21T11:53:29.053 に答える
0

私が考えることができる最も単純なものはこれです(元の質問の例を変更した場合):

wcout << aS->GetName() << L'\t' << static_cast<auto_ptr<Circle>>(aS.get())->GetRadius() << endl;

これ :

static_cast<auto_ptr<Circle>>(aS.get())

タイプの一時オブジェクトを作成します。これは、スコープの最後にあるauto_ptr< Circle >タイプのオブジェクトを破棄します。auto_ptr< Shape >

ここに例があります(私はそれが十分に明確であることを願っています):

#include <iostream>
#include <memory>

struct B
{
    ~B()
    {
        std::cout<<"~B"<<std::endl;
    }
    void foo()
    {
        std::cout<<"foo"<<std::endl;
    }
};
struct A : B
{
    ~A()
    {
        std::cout<<"~A"<<std::endl;
    }
    void bar()
    {
        std::cout<<"boom"<<std::endl;
    }
};

int main() {
    std::auto_ptr< A > a( new A );
    {
        std::auto_ptr< B > b( a.get() );
        b->foo();
    }

    std::cout<<"prepare for the crash"<<std::endl;
}
于 2011-12-20T20:55:54.840 に答える
0

あなたは大丈夫ですauto_ptrスティーブの答えが説明しているように、言語は通常のポインターでこれを行うのに十分スマートです。基本クラスと派生クラスの間でポインターをキャストするには、ポインターの値を変更する必要がstatic_castある場合があり、a は必要に応じてそれを行います。

于 2011-12-20T20:19:23.803 に答える