6 ms·
Poor. Encouraging unnecessary use of 'shared_ptr' really is detrimental to a beginner's growth.
by SuperV1234 4y ago
Poor. Encouraging unnecessary use of 'shared_ptr' really is detrimental to a beginner's growth.
- t6jvcereio 4y agoBeginner here. Could you please explain?
- kiriin 4y ago>std::shared_ptr<sf::RenderWindow> window; >std::shared_ptr<sf::Sprite> background, bird, pipeBottom, pipeTop; None of that should be shared_ptr, in fact they shouldn't be pointers at all. >auto flappy = std::make_shared<FlappyBird>(); >flappy->run(); That would work just fine as a global in main.cpp FlappyBird flappy;
- a_t48 4y agoDisagree - it's very reasonable for resources to be shared.
- ncmncm 4y agoIn most cases, not. Where there is a legitimate reason to share, share. Without, it is just sloppiness.
- a_t48 4y agoIn the context of a game engine, I mean. You may be sharing a model or texture between multiple entities, and want to know when it’s no longer in use.
- ncmncm 4y agoEven there, something higher up the stack probably knows too, and is in a better position to choose a good time to dispose of it.
- Shorel 4y agoThis is C++. You should not pay the performance hit for features you don't need in a particular program. In fact: It is reasonable for C++ programs to NOT use all language features.
- a_t48 4y agoI'm not disagreeing with you.
- ncmncm 4y agoOr, better, as an anonymous expression in main(): FlappyBird().run();
- jdrek1 4y agoShared ownership is a rare case, so in general using shared_ptr should already raise some suspicion. And in this case there is no reason any of the shared_ptr'ed things in the code need to be on the heap so no reason to even have a pointer in the first place. Code like this is effectively what you get when you have someone that doesn't know how to write C++ but writes it anyway and uses pointers everywhere because they either read that C++ is pointer heavy (it's not) or have learned C++ through some course that is actually a course on algorithms and only uses C"++" as example language and is hence at best showing shitty C with iostream and classes straight out the 1980s. Then those people find the (correct) advice of using smart pointers instead of (owning!!!) raw pointers and just put shared_ptr everywhere without thinking about if there actually is a shared ownership to be expressed and/or if the heap allocation is even needed.
- MontagFTB 4y agoA shared pointer is one where ownership can be shared across any part of the application. That sounds great initially, as it assures the thing you’re pointing at will still be alive while you need it. In reality it creates a vague notion of ownership, where no one is responsible for object lifetime, because everyone is. This creates a “functional global” in your application per instance of your shared pointer class. The net effect is a more modern looking architectural morass.
- t6jvcereio 4y agoWhat does ownership mean? Specifically.
- im3w1l 4y agoIf object a owns object b, then it means that a is responsible for managing b's lifetime - that is to delete b and free the memory. Edit: A may also fulfill its obligation by transferring b to a new owner.
- a_t48 4y agoAn example: `std::shared_ptr<sf::RenderWindow> window;` - your main window really doesn't need multiple owners - it can be singly owned by `main()` or whatever the top level construct is for your game with `std::unique_ptr`. If you need to pass the window to some other function, do it by raw pointer or ref, signaling that "here's this object for you to use, but not own". `shared_ptr` should only be used for pointers that actually have multiple owners. The textures here might be a good example for this - you could implement a simple resource system that drops unused resources with `shared_ptr` + `weak_ptr`. As for why - it's mostly around signaling intent and protecting against leaks. It's much easier to reason about ownership if you don't have to worry about some object deep inside your engine hierarchy holding a `shared_ptr` to the object that owns it. This can still happen with unique_ptr, but is much less likely.
- snakey 4y agoGreat explanation, as someone who is new to C++ and actively learning, these perspectives are invaluable. I have been using some shared pointers in a personal project because of its ease of use but I aim to review and refactor this code to follow C++ idioms more appropriately. Thank you!
- typon 4y agoIn these cases I usually opt for gsl::not_null<T>
- SuperV1234 4y agoYou don't even need 'unique_ptr'. The render window on its own is completely fine.
- a_t48 4y agoIn this somewhat toy case - yes. :)
- another_another 4y agoshared_ptr<> is most useful for multithreaded applications where a pointer can be safely shared amongst many threads, where the last one to go out of scope will call delete on the object. To do this safely the shared_ptr<> class maintains a reference count which is protected by a mutex. This is pretty inefficient if you never share a pointer across threads. Better to use unique_ptr<> where the Thing that created it is also the Thing that's responsible for deleting it - after making sure that anything it's shared the pointer with is already safely destroyed (another thread, a collection or some other object).
- tlb 4y agostd::shared_ptr doesn't use mutexes in any implementation I know of. They use atomic instructions for incrementing and decrementing the reference count, which are very fast.
- intelVISA 4y agoPlus their thread-safety is limited to the pointer's control block not the actual object it's pointing to. e: nvm reading hard brain mutex too slow
- another_another 4y agoYou're right, an atomic inc/dec would also do just fine. I stand corrected.
- ncmncm 4y agoOveruse of shared_ptr is called Java Disease in reviews. Most programs don't need to use shared_ptr at all. Side note, there is also no value in making those member functions "protected".
- ncmncm 4y agoThis program, in particular, has no need for any pointers of any kind. They are all better done as simple value objects. I have verified this by deleting "#include memory>", all uses of shared_ptr, changing all "->" to ".", and deleting all unary "*". The window member object is initialized, then, using (drumroll...) member initializer syntax. Most uses of "{}" are better deleted.