4

Prerequisities: To understand this question, please, read the following question and its answer at first: Cast auto_ptr<Base> to auto_ptr<Derived>

At Cast auto_ptr<Base> to auto_ptr<Derived> Steve answered that "Your static_cast would copy the auto_ptr to a temporary, and so aS would be reset and the resource would be destroyed when the temporary is (at the end of the statement)."

I'm interested in the process of temporary creation while static_cast is called. I would like to have the code that I can trace in order to see this effect. I cannot use static_cast<auto_ptr<Circle>> ... because it cannot be compiled, so I need to write some simulation class instead of auto_ptr and watch the process of temporary creation.

I also understand that temporary creation is closely connected with copy constructor call. auto_ptr's ownership loosing is simulated with copy assignment that set the _radius field of source to negative value (I need the simple logical model of auto_ptr).

So, I suggest the following Circle class:

#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. Here we can see that "ownership transferring" is taking place in c2 = c3. BUT I cannot achieve temporary creation in static_cast.

The question is: how to make a small simulation of temporary object creation while static_cast?

I believe Steve that temporary object is created while casting. The only thing I want is to write an example that shows temporary creation. This target has academic reasons.

Can someone clarify how to achieve the effect described in Steve's answer that he posted at the referred topic?

Community
  • 1
  • 1
nickolay
  • 3,643
  • 3
  • 32
  • 40

4 Answers4

3

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';
}
Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
  • YEEESS!! Thanks. Steve, I'm looking forward to ask for your help in my later issues. Thanks all, guys. Here is what I need to hear. – nickolay Dec 21 '11 at 10:14
  • 1
    @daddyM:. The problem with your code was you were making a temporary _pointer_, not a temporary cicle. – Mooing Duck Dec 21 '11 at 16:13
  • @MooingDuck Yep. I've understood this fact and got stack with how to implement non-pointer casting to call overloaded operators. – nickolay Dec 21 '11 at 16:55
1

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.

curiousguy
  • 8,038
  • 2
  • 40
  • 58
0

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.

Community
  • 1
  • 1
David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • Ok. I wonder how to simulate the situation when temporary `auto_ptr` object is created. In my humble simulation `operator =` never called. Of course it's not practical question. It's theoretical investigation only. Again, I'm stuck with simulating `auto_ptr` temporary creation and copy assignment operator call. As you can see `Circle` class is rough simulation of loosing ownership in `auto_ptr`. – nickolay Dec 20 '11 at 20:23
  • I don't understand what you're trying to do. – David Schwartz Dec 20 '11 at 20:25
  • Please, re-read question body. I've added some details. Thanks! – nickolay Dec 20 '11 at 20:34
0

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;
}
Community
  • 1
  • 1
BЈовић
  • 62,405
  • 41
  • 173
  • 273
  • Right! That's Steve wrote in the answer to my original question. I cannot compile the code above (with `auto_ptr`). So, I would like to simulate such situation to track this temporary object creation. `Circle` class is in place of `auto_ptr`. I would like to make `operator =` run while creating temporary during `static_cast' call. Could you help me to write proper simulation code? – nickolay Dec 20 '11 at 21:34
  • @DaddyM I added another example of what happens, but without a temporary object. – BЈовић Dec 20 '11 at 22:05
  • 2
    @DaddyM: `operator=` isn't used when copying in a cast, rather the copy constructor is. So there's no way to do what you seem to want, which is to have the `static_cast` result in a call to `operator=`. – Steve Jessop Dec 20 '11 at 23:16
  • @VJovic Thanks. But it is not what I'm interested in. You showed how `a` will try to call stored object destructor that is already destroyed by `b`. I'm interested in simulate this: `static_cast>(aS.get())` but with another UDF class (original code with `auto_ptr` will not work). – nickolay Dec 21 '11 at 05:38
  • @SteveJessop Nice to see u here. You've understood me. Please, tell how to simulate such situation with UDF class that simulates 'loosing ownership' while copying to the temporary `static_cast`. All I'm wonder in: to trace calls to copy ctor while temporary creating in `static_cast`. – nickolay Dec 21 '11 at 05:42