Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a new object and passing in method parameter [closed]

In Java we can create and pass a new object to a method within its parameters like so:

wrapper.set_state( new Medium() );

What is the equivalent to this in C++? I suppose I could create the object before and then pass it, but being able to create it in the parameter would seem neater.

like image 389
M-R Avatar asked May 01 '16 22:05

M-R


2 Answers

In Java

wrapper.set_state( new Medium() );

creates a new, reference counted, instance of Medium and passes it by reference to wrapper's set_state function.

In C++ the above code is technically valid, in your wrapper class set_state would be defined as:

void set_state(Medium* medium);

But what you would be doing is passing a non-reference counted pointer to a new instance of Medium. You would be responsible for ensuring that it is deleted later. If all set_state did was this:

void set_state(Medium* medium)
{
    this->medium = medium;
}

you would be introducing a memory leak every time you made a second call to set_state. In C++, when you overwrite a raw pointer like this, there is no reference counting. If nobody is pointing to the allocation any more, the allocation is lost/leaked.

You might prefer to pass an object by reference:

void set_state(const Medium& medium)
{
    this->medium = medium;  // copy
}

invoked via:

Medium m;
// populate m
wrapper.set_state(m);

// or

wrapper.set_state(Medium());

or you can pass by value:

void set_state(Medium medium)
{
    this->medium = medium;  // copy
}

// invocation:

Medium m;
// populate m
wrapper.set_state(m);  // copy

Although this is a copy, in some cases the compiler is able to elide out one of the copies (see http://ideone.com/gNICYt)

If you absolutely need to use a pointer (several things will reference the exact same Medium instance) you might want to consider using std::shared_ptr which provides reference counting.

#include <memory>

struct Medium {};
class Wrapper {
    std::shared_ptr<Medium> medium;

public:
    void set_state(std::shared_ptr<Medium> medium) {
        this->medium = medium;  // if we'd called it m_medium, or medium_
        // we could just have written
        // m_medium = medium; or medium_ = medium;
    }
};

int main(void) {
    Wrapper w;
    w.set_state(std::make_shared<Medium>());

    return 0;
}
like image 62
kfsone Avatar answered Sep 18 '22 22:09

kfsone


What is the equivalent to this in C++?

There are multiple similar ways to the implement the quoted Java statement in c++. The exactly same syntax happens to actually be valid c++ assuming the function is expecting a pointer. Whether it is desirable to pass to the function, a raw pointer to a manually allocated object, is something that you must consider. It most likely is not desirable.

The simplest way to create a new object in c++, is to create a temporary. The analogous syntax for creating a temporary and passing it to a function would be:

wrapper.set_state(Medium());

Because Java references are counted, the semantically closest analogue would (probably arguably) be to pass a std::shared_ptr<Medium>. But, because in c++ unlike in Java, you have the option of value semantics but on the other hand, you don't have garbage collection, you cannot assume that you actually should have the same semantics.

like image 27
eerorika Avatar answered Sep 16 '22 22:09

eerorika