static_cast and temporary creation (final edition)

余生长醉 提交于 2019-12-05 16:54:57

In your previous question, auto_ptr is the class that has ownership, and resets the source's pointer to null when it is copied.

Now, Circle is a class that simulates ownership, by resetting its radius to -1 when it is copied. So it's like an auto_ptr in that way, but not in any other way.

So, to observe loss of simulated ownership you need to copy a Circle, which is what you do with copy assignment in the line c2 = c3. Casting a Circle* doesn't copy the object, just the pointer, but casting a Circle does copy the object:

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

Output is -1.

Or if you specifically want to see it with a cast to a derived class:

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';
}

Ok. Here we can see that "ownership transferring" is taking place in c2 = c3. BUT I cannot achieve temporary creation in static_cast.

static_cast<Circle> (c2); 

will "steal" from c2.

David Schwartz

You're fine with the auto_ptr. As Steve's answer explains, the language is smart enough to do this with ordinary pointers. Casting a pointer between base and derived classes can require changing the value of the pointer, and a static_cast will do that when needed.

BЈовић

The simplest I could think of is this (if you change the example in your original question) :

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

This :

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

creates a temporary of type auto_ptr< Circle >, which destructs the object of type auto_ptr< Shape > at the end of the scope.

Here is an example (I hope it is clear enough) :

#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;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!