Originally Posted by
CornedBee
Still, in the end, your example use case comes down to trying to use a thread-affine object from multiple threads.
Unless there are more examples.
Originally Posted by
CornedBee
Forbidding references and pointers is not the way to make thread-affine objects safe.
Already been mentioned several times.
Originally Posted by
CornedBee
What it achieves is preventing the (useful) use of references and pointers. (One example: if your smart pointer is thread-safe, then copying has the thread-safe reference counting overhead. If you want to avoid that, you could pass the smart pointer by reference within any single thread, which is perfectly safe and faster than copying it.)
You have a point, but I designed the class to be thread safe or not. User choice. If no thread security is done, it's faster and not needed on multiple threads.
You might have a point in passing by reference if it's thread safe and multiple threads, of course, but I don't like the idea that another function will be using the memory without increasing the ref counter.
Originally Posted by
CornedBee
To enforce thread affinity, you need to check thread affinity. Basically, in the debug version of your program, the smart pointer should grab the executing thread's ID on construction and assert() on every dereference that the executing thread's ID is the same as the one taken on construction. That is (assuming N2320 C++ threading):
That's another excellent idea! I will add checks if the class is put to not be thread safe is the creating thread is actually trying to access the object.
UPDATE:
I actually thought of something else that might put references at risk.
One is calling Delete() from a function:
Code:
void foo(pp<int>& pTest)
{
// ...
pTest.Delete(); // Oops, decrements the reference count and destroys the memory.
// ...
}
int main()
{
ppnew<int> pTest;
foo(pTest);
int n = *pTest; // Oops, access violation, pTest == NULL
// ...
}
Another reason why passing by reference might not always be such a good idea. I know this is stupid and you should probably (or maybe) assign cost, but anyway, here goes:
Code:
void foo(pp<int>& pTest)
{
pTest = newpp(new int, false); // newpp(T* p, bool bArray); // NOT INTENTIONAL! Supposed to be used locally, but isn't due to being passed by reference.
*pTest = 1;
}
int main()
{
ppnew<int> pTest(0);
int n = *pTest; // n == 0
foo(pTest);
int n = *pTest; // n == 1
}