jlack
jlack

Reputation: 315

How to check if an object==this in c++

I have spent a great deal of time programming in Java and a decent amount of time writing c++, but I have run into an issue I haven't been able to solve. In a Java class I can simply write the following,

public void doOperation(object a)
{
    if(a != this)
    {
        set(a); // just some method that sets this.a = object.a
    }

    doOperation();
}

public void doOperation()
{
   this.a = pow(this.a,3);
}

The part I am having trouble implementing in c++ is the if statement where I check if the argument object is equal to this. I have tried this in c++

object::doOperation(object a)
{
    if(a != this)
    {
        set(a);
    }

    doOperation();
}

object::doOperation()
{
    this->a = pow(this->a,3)
}

The error I get reads, "no match for ‘operator!=’ (operand types are ‘object’ and ‘object* const’)". Thanks in advance for anybody who can help!

Upvotes: 2

Views: 5551

Answers (4)

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145339

In Java most objects are passed around as references. To avoid aliasing problems you may then need to check for reference equality: are these two apparently distinct objects, really distinct, or do the references refer to the same object?

In C++ objects are often passed as values, copying their values. And for values it doesn't make sense to check for object identity. E.g. a function argument passed by value, as in your object::doOperation(object a) example, will always have an address different from everything else at that point in the program execution (it's freshly allocated).

Still there are some cases where objects are passed by reference (or pointer), and where self-check is appropriate.

For example, a copy assignment operator might go like this:

auto My_class::operator=( My_class const& other )
    -> My_class&
{
    if( &other != this )
    {
        values_ = other.values_;    // Avoid this work for self-assign.
    }
    return *this;
}

The self-check can also be crucial for correctness, although with use of standard library containers and smart pointers correctness can usually be ensured without any self-check.

Upvotes: 1

Peter
Peter

Reputation: 36617

If an object has been passed by value as in

void object::doSomething(object x)
{
    // whatever
}

then it is not necessary to compare with this. Even of the caller does

some_object.doSomething(some_object);

the x is a temporary copy - i.e. so a different object is guaranteed.

If the argument is passed by reference or argument then remember that this is a pointer and not a reference (unlike Java in which those concepts are entwined), for example;

void object::doSomething(object *x)
{
     if (this != x)
     {

     }
}

and

void object::doSomething(object &x)
{
     if (this != &x)
     {

     }
}

The latter assumes that object does not have an interfering operator&(). If that assumption is invalid then, in C++11 use addressof(x) (where addressof() is specified in <memory>. Before C++11, the tricks to get address of x are a little more indirect (e.g. a sequence of casts).

Personally, I don't do such tests at all. Instead, I simply do

void object::doSomething(object &x)
{
     object temp(x);

      // do things with temp and *this

      std::swap(x, temp);
}

which relies on working copy semantics, but also gives more exception safety. If a class makes the above prohibitive, then that is more usually a problem with class design (better to find another way to avoid the need to compare with this).

Upvotes: 0

Chris Beck
Chris Beck

Reputation: 16204

You can simply pass "a" by reference, take a pointer to "a" and compare it with "this", like so:

object::doOperation(object & a)
{
    if(&a != this)
    {
        set(a);
    }

    doOperation();
}

object::doOperation()
{
    this->a = pow(this->a,3)
}

This is a standard way that people would e.g. implement copy assignment operators in C++. It's not always done this way, but often the implementation of that will take a const reference to an object, and use a check against "this" to prevent self assignment.

Edit: Let me try to take a broader view, which might be more useful to you.

In Java, objects are implicitly passed around by reference and not by value, and they are garbage collected also, automatically destroyed when no-one needs them anymore.

The closest way to get that kind of semantics in C++ is to pass around std::shared_ptr<A> when in java you would have passed A. Then, when you need to compare against this, you can use the get method to get a raw pointer from the shared pointer and compare it literally against this. OR, if you use the std::enable_shared_from_this template when you define your class, you can use shared_from_this to get a shared_ptr<A> to this at any point in your member functions, and compare the shared_ptr's directly.

I'm assuming you are using C++11, otherwise you would use boost headers for that stuff.

Note also the stuff about "weak_ptr" which you might need to use if you have cyclic references.

Upvotes: 7

Amit
Amit

Reputation: 46341

That's because this is a pointer type in C++. If your function signature would use a pointer as well, it would work:

object::doOperation(object* a)
{
    if(a != this)
    {
        set(a);
    }

    doOperation();
}

Upvotes: 1

Related Questions