Why don't these shared_ptrs point to the same container?

I have a Model class:

class Model { ... boost::shared_ptr<Deck> _deck; boost::shared_ptr<CardStack> _stack[22]; }; 

Deck inherited from CardStack .

I tried to make _stack[0] point to the same as _deck indicates by going:

 { _deck = boost::shared_ptr<Deck>(new Deck()); _stack[0] = _deck; } 

_deck of _stack[0] seems to create a copy of _deck . (I know this because changes to _stack[0] do not lead to changes to _deck .) How can I get them to point to the same thing?

Ok - no copy constructor is called. I checked this by doing it and seeing if it was called - it is not.

However - I have a function that works with CardStack objects:

 void TransferSingleCard(CardStack & src, CardStack & dst, Face f) { if( !src._cards.empty() ) { src._cards.back().SetFace(f); dst.PushCard(src._cards.back()); src._cards.pop_back(); } } 

Now - when I call:

 { TransferSingleCard(*_stack[DECK], _someotherplace, FACEDOWN); std::cout << *_stack[DECK]; std::cout << *_deck; } 

I get this output (where std :: cout on CardStack will print the size of this stack):

 Num(103) TOP Num(104) TOP 

... so I did (wrong?) that _stack[DECK] points to something else.

Deck

 class Deck : public CardStack { public: Deck(int numsuits=2, StackIndex index = NO_SUCH_STACK ); Deck::Deck( const Deck & d); int DealsLeft() const; void RecalcDealsLeft(); private: int _dealsleft; }; 
+4
source share
4 answers

This example is obtained from @Neil's answer, trying to imitate what you say. Could you verify that it works as expected (A and B have the same score) on your system.

Then we could try changing this code or your code until they match.

 #include <boost/shared_ptr.hpp> #include <iostream> class A { public: virtual ~A() { std::cerr << "Delete A" << std::endl; } int _count; void decrement() { _count --; } }; class B : public A { public: virtual ~B() { std::cerr << "Delete B" << std::endl; } }; int main() { boost::shared_ptr<B> b(new B); b->_count = 104; boost::shared_ptr<A> a; a = b; a->decrement(); std::cerr << "A:" << a->_count << std::endl; std::cerr << "B:" << b->_count << std::endl; return 0; } 

EDIT:

So, from the comment, we know that the source pointers are correct, so now we need to track.

Or:

  • log pointers to see when they change.
  • Use watchpoints in the debugger to see when the pointer changes.
  • Use the third common pointer to see which pointer has been changed.
  • Introduce a function that simultaneously changes both pointers.
+1
source

It is unclear what you are asking - consider this code:

 #include <iostream> #include "boost/shared_ptr.hpp" using namespace std; struct A { virtual ~A() { cout << "destroyed" << endl; } }; struct B : public A { }; int main() { boost::shared_ptr<B> b( new B ); boost::shared_ptr<A> a; a = b; } 

Only one β€œdestroy” message appears indicating that no copy was made.

+2
source

I think the problem is that you are assigning different types here. boost::shared_ptr is a template, and templates are not polymorphic, even if the type is in them. So what happens is that your compiler sees the assignment from boost::shared_ptr<Deck> to boost::shared_ptr<CardStack> and notices that it can perform the assignment by invoking the copy constructor for CardStack to duplicate the Deck object.

I think you want the assignment to look like this:

 _stack[0] = boost::static_pointer_cast<CardStack>(_deck); 

What will the conversion do as you expect.

+1
source

I think you might need shared_array for _stack . Take a look at the documentation on shared_ptr ; from boost.org, in particular:

http://www.boost.org/doc/libs/1_42_0/libs/smart_ptr/shared_ptr.htm

"Normally, shared_ptr cannot correctly hold a pointer to a dynamically allocated array. See shared_array for this use."

Also, pay attention to the T* get() function (not to be used without good reason), which returns a raw pointer held by a managed pointer (shared_ptr in this case).

+1
source

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


All Articles