[C++] Checking for 'this' inside it's class

Started by
29 comments, last by phresnel 14 years, 7 months ago
Quote:Original post by RealMarkP
Is there a way that I can check if the 'this' keyword was passed into a class


"The 'this' keyword" isn't a "thing" that can be passed. It's a way of obtaining a pointer to an object. (Also, "passed into a class" is nonsensical; you apparently mean "passed as a parameter to a constructor".)

There is no way to determine whether a pointer to an object was generated by code using the 'this' keyword or code not using the 'this' keyword, because either way, it's the same object, and thus, any pointers to the object are identical.

It almost seems like what you want is to enforce that the constructor is only called from member functions, and then check whether the passed-in value points to the object that initiated the call. But what do you think you could possibly accomplish by checking this, anyway? Show some code, so we can at least get closer to the question you really want to ask.

Quote:I know how to check if a pointer being passed in is on the Stack or the Heap


No, you don't. Not in a standards-compliant, platform-agnostic way, anyway - because it doesn't exist. If you are doing it by checking address ranges (the only thing I can think of), it won't necessarily work on any other platform.

Quote:but the 'this' keyword will always be on the Heap if the class itself was dynamically allocated.


Again, your terminology is sloppy. The 'this' keyword will yield a pointer to an object; and if that object was dynamically allocated, then the pointer will point to a heap location, because that's what "dynamically allocated" means. But this doesn't really have anything to do with what you're asking at all.

Quote:Original post by MaulingMonkey
Quote:Original post by Atrix256
You can always check if this == 0

The only way for this to ever be false...


I wonder if you realize that what you said could be interpreted as either exactly what you meant, or exactly the logical opposite :)
Advertisement
Quote:Original post by Zahlman
I wonder if you realize that what you said could be interpreted as either exactly what you meant, or exactly the logical opposite :)


That would explain why I originally wrote "... this to ever be true" before I 'corrected' it during editing <_<;
Ok, whoa. I forget to check my post and a million people post.

Let me clarify. The way I check weather a pointer is on the Stack or Heap is by address range checking. I know it's architecture specific and It doesn't bother me (for now, anyways).

To be more specific, if someone passes a pointer into a smart pointer class, it will be reference counted and eventually deleted when the ref count reaches zero. However, if a smart pointer is used within a class and the 'this' pointer is passed into it, I would like it to somehow determine that it should not be deleted. My fall back is to manually specify the smart pointer to not delete the pointer when ref reaches zero.

So the point of my question was to determine if 'this' was passed into a function. If this is not possible then I can accept that - this is purely exploratory.
------------Anything prior to 9am should be illegal.
Smart pointers are supposed to be smart about their business. They are not supposed to be NannyStatePointersThinkingOfTheChildren<T>.

As long as you accept only pointer and not reference semantics, it's impossible to point a pointer to stack object by mistake.

This question pops up every once in a while, but the basic conclusion is that it's not worth pursuing. Also, since smart pointers are effectively part of C++, their semantics should no longer be a mystery to anyone working in C++, so this isn't really needed.

Boost doesn't bother with it, and it doesn't seem to be any big problem.
Quote:Original post by Antheus
Smart pointers are supposed to be smart about their business. They are not supposed to be NannyStatePointersThinkingOfTheChildren<T>.


This is true, however I did add logic to determine if the pointer is Heap/Stack based in order to differentiate between:

Ptr<CFoo>; p = new CFoo();

and..
CFoo a;Ptr<CFoo> p = &a;


So that when it runs out of scope it doesn't accidentally delete the stack based pointer. Tracking down an accidental delete of a Stack based value is a pain. But this is beside the point.

Quote:As long as you accept only pointer and not reference semantics, it's impossible to point a pointer to stack object by mistake.


I don't accept references to objects, only pointers.

Quote:This question pops up every once in a while, but the basic conclusion is that it's not worth pursuing. Also, since smart pointers are effectively part of C++, their semantics should no longer be a mystery to anyone working in C++, so this isn't really needed.


I did some more googling on this topic and with little results. I doubt there is a way to make this work. I will stick with my original way of disabling auto deletion.

Ptr<CFoo> p = this;p.deleteOnZeroRef(false);


Quote:Boost doesn't bother with it, and it doesn't seem to be any big problem.

This is true. One other option is to have a derived class that should only be used with the 'this' pointer.

ThisPtr<CFoo> p = this; // Automatically turns off deletion when reference reaches zero.
------------Anything prior to 9am should be illegal.
Another problem with such a smart pointer is that you might easily end up holding a pointer to an object that has gone out of scope. Smart pointers are normally there to control the lifetime of an object, but you don't have such control over stack-based variables.
Quote:Original post by RealMarkP
To be more specific, if someone passes a pointer into a smart pointer class, it will be reference counted and eventually deleted when the ref count reaches zero. However, if a smart pointer is used within a class and the 'this' pointer is passed into it, I would like it to somehow determine that it should not be deleted.

Meh. Don't bother. If you try to make safe bad coding habits, you just encourage the use of bad coding habits. It's a mistake to construct a reference counted smart pointer from a stack object.
Quote:Original post by SiCrane
Quote:Original post by RealMarkP
To be more specific, if someone passes a pointer into a smart pointer class, it will be reference counted and eventually deleted when the ref count reaches zero. However, if a smart pointer is used within a class and the 'this' pointer is passed into it, I would like it to somehow determine that it should not be deleted.

Meh. Don't bother. If you try to make safe bad coding habits, you just encourage the use of bad coding habits. It's a mistake to construct a reference counted smart pointer from a stack object.

Perhaps you could issue a run-time warning if you could detect that someone is trying to do that. That would be a more interesting application of what he is asking (not that I have seen a clear formulation of what the question in this thread really is).
Quote:Original post by RealMarkP

So that when it runs out of scope it doesn't accidentally delete the stack based pointer. Tracking down an accidental delete of a Stack based value is a pain. But this is beside the point.


Yes, there are many ways to break smart pointers.

People who make such *mistakes* should be using managed languages. People who deliberately abuse such functionality, better know what they are doing.

Here is a counter point:
Ptr<Foo> ptr;Foo onStack;*((Foo*)(((char*)(&ptr))+4)) = &onStack // let's use the stack pointer*((int*)(((char*)(&ptr))+8)) = 9999; // let's rev up the ref count so it doesn't get deleted


In C++, it is impossible to protect against abuse.
Quote:Original post by RealMarkP
So that when it runs out of scope it doesn't accidentally delete the stack based pointer.
Constructing a shared pointer to a stack object is a mistake, going out of your way to make it work implies that it's not a mistake. If you're still worried about this for some reason then better to make it emit a compile-time warning or even throwing an exception would do.

Rarely, but sometimes, the user might actually want to create a smart pointer to a stack allocated object. Boost's shared_ptr handles this by allowing them to specify a custom deleter:

foo f;
boost::shared_ptr<foo> p(&f, null_deleter());

This essentially makes the smart pointer dumb, when the reference count reaches zero nothing happens.

It also solves your smart pointer to this problem.

This topic is closed to new replies.

Advertisement