Static_cast and temporary creation (final version)

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

In Cast auto_ptr <Base> to auto_ptr <Derived> Steve replied that "Your static_cast will copy auto_ptr to a temporary one, and therefore aS will be reset, and the resource will be destroyed if it is temporary (at the end of the expression)."

I'm interested in the temporary creation process when static_cast is static_cast . I would like to have code that I can track to see this effect. I cannot use static_cast<auto_ptr<Circle>> ... because it cannot be compiled, so I need to write some modeling class instead of auto_ptr and see the process of creating it temporarily.

I also understand that temporary creation is closely related to calling the copy constructor. auto_ptr Property identification is modeled with copies that set the _radius source _radius to a negative value (I need a simple auto_ptr boolean model).

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 see that the “transfer of ownership” occurs at c2 = c3 . BUT I cannot create a temporary creation in static_cast .

The question arises: how to do a little modeling of creating a temporary object while static_cast ?

I believe this temporary object is created during casting. The only thing I need is to write an example showing a temporary creation . This goal has academic reasons.

Can someone clarify how to achieve the effect described in the text of Steve, which he published in the mentioned topic?

+4
source share
4 answers

In the previous question, auto_ptr is a class that owns and resets the original pointer to zero when it is copied.

Now Circle is a class that mimics ownership by dropping its radius to -1 when copying it. Thus, it is similar to auto_ptr in this way, but not in any other way.

So, in order to observe the loss of simulated ownership, you need to copy the Circle , what do you do with the copy destination in line c2 = c3 . Casting a Circle* does not copy the object, just a pointer, but when you click Circle copies the object:

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

The output is -1.

Or, if you specifically want to see it 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'; } 
+3
source

Ok Here we see that the “transfer of ownership” occurs at c2 = c3. BUT I cannot create a temporary creation in static_cast .

 static_cast<Circle> (c2); 

will "steal" from c2 .

+1
source

You are fine with auto_ptr . As Steve explains the answer , the language is smart enough to do this with regular pointers. Setting a pointer between the base and derived classes may require changing the value of the pointer, and static_cast will do this if necessary.

0
source

The simplest one 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; 

It:

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

creates a temporary type auto_ptr< Circle > , which destroys an object of type auto_ptr< Shape > at the end of the region.

Here is an example (hopefully this 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; } 
0
source

Source: https://habr.com/ru/post/1387262/


All Articles