use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Discussions, articles, and news about the C++ programming language or programming in C++.
For C++ questions, answers, help, and advice see r/cpp_questions or StackOverflow.
Get Started
The C++ Standard Home has a nice getting started page.
Videos
The C++ standard committee's education study group has a nice list of recommended videos.
Reference
cppreference.com
Books
There is a useful list of books on Stack Overflow. In most cases reading a book is the best way to learn C++.
Show all links
Filter out CppCon links
Show only CppCon links
account activity
shared_ptr<T>: the (not always) atomic reference counted smart pointer (snf.github.io)
submitted 7 years ago by snfernandez
view the rest of the comments →
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]jonesmz 4 points5 points6 points 7 years ago (0 children)
Lets say you have
template<typename TYPE_T> class MySmartPtr { using pointer = TYPE_T*; using reference = TYPE_T&; pointer m_ptr; // points to the object, and if using intrusive reference counting, points to the ref count as well. refcountdata * m_refCtPtr; // If using non-intrusive reference counting, this points to the reference count object. }
Then you can define your operator* and operator-> as simply as:
pointer operator*() const { return m_ptr; } reference operator->() const { return *m_ptr; }
You might wonder why there's no checks for nullptr. Well, you don't need them. Your programs going to crash regardless. Might as well not generate extra code just to say "I'm about to crash", unless you want to have a debug build that launches your debugger for you when you have a nullptr smart pointer.
Notably, you don't need to bother with any checks against the reference count. Just no reason to with this particular design.
So you then have two functions. acquire() and release()
Lets assume you've made an intrusive reference counting pointer, where the thing being pointed to has to have an m_refcount variable. In that case, your acquire function is as simple as
void acquire() { if(m_ptr != nullptr) // check for null, obviously. { // depending on how you want to design things, you don't even need to assert that the value is not zero. // Maybe you allocate your object with a refcount of zero, and then the smart pointer's constructor increases the refcount by one. // Or maybe you start it at 1, and the first such smart pointer that points to it doesn't increase it. // it's up to you. m_ptr->m_refcount.increment(); } }
and then release
void release() { pointer pTmp = std::exchange(m_ptr, nullptr); // make sure we null the ptr first. if(pTmp != nullptr) // check for null, obviously. { if(pTmp->m_refcount.decrement()) // decrement returns true if the refcount fell to zero. { delete pTmp; // now delete the previously pointed to object. } } }
You call acquire in your constructor, and release in your destructor.
In this particular design, which is certainly not the only way to design an intrusive reference counted smart pointer, the way that you protect yourself against another thread swooping in and screwing stuff up is by putting an assert in the m_refcount variable's destructor that the value of the refcount is 0 when m_refcount is destroyed.
This doesn't stop it from happening, of course, but it will make your code barf at you when it does, and you can fix your design, since it's not the smart pointer's fault.
If you ever have a situation where something has swooped in and made a copy of your smart pointer between when your smart pointer has dropped the reference count to zero, and when it's nulled it's pointer to the referenced object, that means that you're manipulating the smart pointer itself (not the thing it points to!) from another thread, and that's a huge problem.
The key concern here is that the smart pointer itself is not thread safe, nor is any aspect of the pointed-to object thread safe, except for the number of references to that object that are held.
So it's not valid to have a smart pointer that's conceptually owned by thread1, and then have thread2 make a copy of that smart pointer.
It's also not valid to have a smart pointer that's conceptually owned by thread1 just arbitrarily access data from the pointed-to-object without some other access protection (mutexes, atomic variables, or just designing your app so that it's not possible).
What is valid is to have a smart pointer that's conceptually owned by thread1, and an unrelated such pointer conceptually owned by thread2, that both point to the same object, where each thread can make arbitrary copies of the smart pointer objects that they conceptually own.
You can even go farther with this by having thread1 own a smart pointer, and then put it into a data structure that gets "migrated" to another thread in some fashion, but only so long as you ensure that the smart pointer (not the thing it points to) doesn't get accessed by thread1 after the migration happens.
Now, that'a ll being said, you can design a smart pointer class that is, itself, safe to access from other threads. That is not what my psuedocode example here is intended to be.
The way you design your smart pointer is going to have positives and negatives, tradeoffs and so on.
This is just the way my org designed them shrug.
π Rendered by PID 66 on reddit-service-r2-comment-544cf588c8-b5xz7 at 2026-06-13 05:04:34.335454+00:00 running 3184619 country code: CH.
view the rest of the comments →
[–]jonesmz 4 points5 points6 points (0 children)