How to assing this to NULL?

C

Cheney Stallman

I have a class as following:

class X
{
public:
static X* Create()
{
return new X();
}

void Destroy()
{
delete this;
// try assign this to NULL, but failed.
this = NULL;
}

private:
X(){}
};

int main()
{
X* pX = X::Create();
pX->Destroy();

// test the validation of pX.
// I want the Destroy function set the pX to NULL.
if (pX){
// do something
}

return 0;
}

My problem is on line compiler complain error:
this=NULL;

Does there exist some method to set the this pointer to NULL?
Any response is appreciate.
 
R

Rolf Magnus

Cheney said:
void Destroy()
{
delete this;
// try assign this to NULL, but failed.
this = NULL;
}

private:
X(){}
};

int main()
{
X* pX = X::Create();
pX->Destroy();

// test the validation of pX.
// I want the Destroy function set the pX to NULL.
if (pX){
// do something
}

Note that the this pointer within Destroy is _not_ pX within main. It's not
the same pointer. Even if it were possible to change the this pointer, pX
wouldn't change.
return 0;
}

My problem is on line compiler complain error:
this=NULL;

Does there exist some method to set the this pointer to NULL?

No. It wouldn't make sense anyway. The this pointer is constant.
 
P

paulius-maruska

I think you should do it like this (i modified original code):
class X
{
public:
static X* Create()
{
return new X();
}

static void Destroy(X** x)
{
// you must check if x or *x is not NULL
assert(NULL != x);
assert(NULL != *x);

delete *x;
// try assign this to NULL, but failed.
*x = NULL;
}

private:
X(){}
};

int main()
{
X* pX = X::Create();
X::Destroy(&pX);

// test the validation of pX.
// I want the Destroy function set the pX to NULL.
if (pX){
// do something
}

return 0;
}
 
K

Kai-Uwe Bux

Cheney said:
I have a class as following:

class X
{
public:
static X* Create()
{
return new X();
}

void Destroy()
{
delete this;
// try assign this to NULL, but failed.
this = NULL;

this is a const pointer. Your compiler is correct.
}

private:
X(){}
};

int main()
{
X* pX = X::Create();
pX->Destroy();

// test the validation of pX.
// I want the Destroy function set the pX to NULL.

Now, that cannot possibly be achieved by a method inside the object. How
should that object know from where you point at it? In order to change the
value of pX, you need to pass a *reference* to pX to the method. All the
method Destroy() sees, however, is the *value* of pX (accessible as the
value of this). Consider a static function:

class X{
public:

static
void Destroy ( X* & p ) {
// note the pass by reference
delete p;
// delete gracefully deals with this even if p==0.
p = 0;
// now we change p.
}

}


Then you could do:

X* pX = X::Create();
X::Destroy(pX);

if (pX){
// do something
}

return 0;
}


Best regards

Kai-Uwe Bux
 
C

Cheney Stallman

Thanks. It made me clear. That means:
this != pX.
Does my understood right?


PS:
I know *this* is a const pointer.
However we can convert it forcely, for example:
X* _this = const_cast<X*>(this);
_this = 0;
This code can compile, but it does not work as I expected. :-(
 
J

John Carson

Cheney Stallman said:
Thanks. It made me clear. That means:
this != pX.
Does my understood right?

No. this == pX, i.e., this and pX have the same value. However, they are two
different variables. For an analogy, consider:

int x = 5;
const int y = x;

Then x== y, but you can't set y equal to zero (because it is const) and
doing so would have no effect on x anyway because x and y are different
variables.
 
G

Greg Comeau

I have a class as following:

class X
{
public:
static X* Create()
{
return new X();
}

void Destroy()
{
delete this;
// try assign this to NULL, but failed.
this = NULL;
}

private:
X(){}
};

int main()
{
X* pX = X::Create();
pX->Destroy();

// test the validation of pX.
// I want the Destroy function set the pX to NULL.
if (pX){
// do something
}

return 0;
}

My problem is on line compiler complain error:
this=NULL;

Does there exist some method to set the this pointer to NULL?
Any response is appreciate.

Once upon a time, the above was a technique.
But also, a while ago now, it was deemed that
considering this was not an assignable lvalue to be ugly and
error prone, and therefore it is no longer an assignable lvalue.
If you have some special allocation needs,
then consider _class specific_ operator new and delete's.
 
G

Greg Comeau

Once upon a time, the above was a technique.
But also, a while ago now, it was deemed that
considering this was not an assignable lvalue to be ugly and
error prone, and therefore it is no longer an assignable lvalue.
If you have some special allocation needs,
then consider _class specific_ operator new and delete's.

Just to be clearer:

struct xyz {
void *operator new(size_t);
void operator delete(void *);
// ...

Now it becomes transparent, works with inheritance, etc.
 
C

Cheney Stallman

But this does not work, note that here
void operator delete(void* p);
in this function declare p is not a reference. though we can change
the value of p in delete(void* p), but actual p does not affected.
maybe following style delete will work:
void operator delete(void*& p);
But the compiler does not allow this declare.
 
G

Greg Comeau

But this does not work, note that here
void operator delete(void* p);
in this function declare p is not a reference. though we can change
the value of p in delete(void* p), but actual p does not affected.
maybe following style delete will work:
void operator delete(void*& p);
But the compiler does not allow this declare.

Class specific op new/delete is offered as an alternative strategy
from the legacy "assignment to this" technique of memory allocation.
Which is what I thought you were doing.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,008
Latest member
HaroldDark

Latest Threads

Top