0

I am working with a class that is mostly working fine, but I am doing some functionality that I might be having a recursive function return a NULLpointer of the class type as a control, and so it might be assigning a NULL pointer to my class object so long story short:

Thing& Thing::operator=(Thing * _other){
    if (_other == NULL){
        *this = NULL;        // compiler throws here
        return *this;    
    }
    // does other assignment work
    return *this;
}

my compiler VS2010 throws that this is not an I-value. so how do I set the value to NULL, or is it even possible to set an item to NULL from inside?

EDIT: modified this to *this though for some reason now the program breaks with infinite calls to the assignment operator. no idea what is going on

gardian06
  • 1,496
  • 3
  • 20
  • 34
  • 2
    `*this = NULL` calls your operator again, which goes into the if, which calls your operator, etc. If you want to write copy-assignment operator, it should take argument by const reference or a value (see: copy-and-swap idiom). – Cat Plus Plus Mar 12 '12 at 08:17
  • Why don't you use a copy constructor? – Alex Mar 12 '12 at 08:25
  • @Alex similar would have to be done in a copy constructor. because most copy constructors simply copy the object arg, and if you try to copy NULL data most debuggers/exectables crash, or should. – gardian06 Mar 12 '12 at 08:31
  • @gardian06: Well, no. `NULL` is just 0, and you can obviously copy that. You can't _dereference_ it, which is another matter. The real problem is that you're treating `_other==0` as "no Thing", and then try to make a copy of "no Thing". That doesn't make sense. – MSalters Mar 12 '12 at 09:14
  • It would be interesting to see gardian06's use case for this method, especially when passing NULL. – Joseph Mansfield Mar 12 '12 at 09:28
  • @sftrabbit this is a functionality driven iterative development were we are focusing on the functionality rather then documentation, and the reason to pass `NULL` is for the purpose of fast break out. though there could be easier implementations (testing against a specific var instead of `NULL`, but it can be a quicker reaction for `if(this == NULL)` then doing `if(this.member == valMeaningNULL)` – gardian06 Mar 13 '12 at 05:37

5 Answers5

2

You cannot directly set a value to the this pointer. Hence

this = NULL;

is semantically and syntactically wrong.

You can use exceptions to check if _other is NULL. For example:

class null_object_exception : public virtual exception {};
...
if (_other == NULL) throw null_object_exception();

To perform a NULL assignment:

Thing the_thing, other_thing;
try { the_thing = &other_thing; }
catch( const null_object_exception& e ) { the_thing = NULL; }
ApprenticeHacker
  • 21,351
  • 27
  • 103
  • 153
2

You are trying to write a "nullable" class. Consider the "null" state to be one of the states an instance of Thing can be in, and don't convolute it with pointer semantics.

The general method would be to add a boolean flag to your class that keeps track of whether an instance is in null state or not. I would implement it like this:

class Thing
{
private:
    bool m_null;

public:
    void setnull() { m_null = true; }
    bool isnull() const { return m_null; }

    Thing() : m_null(true) {}

    ... // rest of class
};

And now the default assignment operator works fine.

Andrew Tomazos
  • 66,139
  • 40
  • 186
  • 319
1

You CANNOT assign to this.

Also, you should take your arguments by const reference, so Thing& operator= (const Thing& other)

There's a great SO question in C++-faq tag about operator overloading, you can find it here

Community
  • 1
  • 1
Tony The Lion
  • 61,704
  • 67
  • 242
  • 415
  • 2
    `this` is not `const`, it yields an rvalue. – Cat Plus Plus Mar 12 '12 at 08:15
  • @CatPlusPlus after doing some checking this is a const* to the current object, and can be assigned to by saying`*this` though it just treats it like a different object – gardian06 Mar 12 '12 at 08:28
  • 1
    @gardian06: It's not a const pointer, it's an expression that yields an rvalue pointer. It might be a pointer to const, but that depends on constness of the object. Dereferencing it doesn't yield another pointer, it yields a (maybe const) reference to the object — you never modify `this` pointer, because it's impossible. – Cat Plus Plus Mar 12 '12 at 08:30
  • @CatPlusPlus I changed my answer accordingly – Tony The Lion Mar 12 '12 at 08:37
1

what are the member variables of Thing class? if you want to show that the object is somehow without value or not intialized, you would better assign fileds 0 (for integers) and null(for pointers) etc, instead of assigning "this" which is constant.

rene
  • 156
  • 1
  • 2
  • 11
  • this does require changing tests, but it also seems to be one of the most straight forward, and doesn't make me have to change a bunch of my implementation – gardian06 Mar 12 '12 at 09:23
  • Maybe it is better to right a member function `void Thing::initializeNull(){}` and do these assignments in it and call it whenever you need and in the default constructor of Thing. – rene Mar 12 '12 at 10:02
1

Short answer, no, you can't assign to this in C++.

Longer answer; for your assignment operator to even be called, you'd have to have a construct like;

MyObject a;
a = NULL;    // can change the content of `a` but not which object the name `a` refers to.

If you're thinking about this construct;

MyObject *a;
a = NULL;

your assignment operator won't even be called since it is an operator on the object, not the pointer. Assigning to the pointer a will work without you defining an assignment operator.

Joachim Isaksson
  • 176,943
  • 25
  • 281
  • 294
  • will "MyObject a = NULL" even call Thing::operator=(Thing* _other)? NULL is not of type Thing*, so why would that overload be called? – KJ Tsanaktsidis Mar 12 '12 at 08:21
  • @KJTsanaktsidis It would make sense that it wouldn't, but yes. If you have multiple overloads taking pointers, NULL will cause a compilation error due to ambiguous overload. – Joachim Isaksson Mar 12 '12 at 08:29