Home > OS >  When do instantiate a reference vs the object itself in C ?
When do instantiate a reference vs the object itself in C ?

Time:09-06

auto& myOBj_ref = MyClass();

vs

auto myObj = MyClass()

I'm not talking about passing a parameter to a function, but inside a function itself, what are the usual use cases for instantiate a reference to an instance vs just the object itself?

CodePudding user response:

auto myOBj_ref& = MyClass();

This is syntactically wrong, so the program is ill-formed.

auto& myOBj_ref = MyClass();

This is also ill-formed, because a prvalue such as the temporary object cannot be bound to an lvalue reference to non-const.

const auto& myOBj_ref = MyClass();

auto&& myOBj_ref = MyClass();

Although these work, there's no point in using lifetime extension this way.

auto myObj = MyClass();

Use this. Or, you can also use:

MyClass myObj{};

what are the usual use cases for instantiate a reference to an instance vs just the object itself?

The usual case for using lifetime extension of object bound to a reference is where the object is a reference wrapper (or similar), and it is used in a template where it might in other case be a reference:

void foo(auto function_object)
{
    // ref could be reference
    // or a wrapper whose lifetime will be extended
    auto&& ref = function_object(); 

// usage
T& returns_ref();
std::reference_wrapper<T> returns_wrapper();

foo(returns_ref);
foo(returns_wrapper);

CodePudding user response:

Edit: see @user17732522 comment about using const MyClass& myObj = MyClass();, which might answer question better.


I think you have a misunderstanding about references to where an object is initialized:

You can initialize an instance of a class on the heap using the new keyword. If you do this, you get a pointer to your object, so you should use MyClass* myObj = new MyClass() to initlaize it. You can dereference the pointer yourself, but you must remember to delete the pointer reference later.

Or, you can initialize an instance of a class on the stack, which returns a prvalue (pure value, not reference) to the object. Here you can use Myclass myObj = MyClass(), you do not get a pointer but a prvalue to your object.

#include <iostream>

using namespace std;

class MyClass {
    public:
    void printHi() {
        std::cout << "hi";
    }
};

int main()
{
    
    MyClass* myObj = new MyClass();
    myObj->printHi(); // prints Hi
    delete myObj; // don't forget to free objects initialized using `new`
    
    MyClass myObj2 = MyClass();
    myObj2.printHi(); // prints Hi
    
    
    // error: invalid initialization of non-const reference of type ‘MyClass&’ from an rvalue of type ‘MyClass*’
    // MyClass& myObj = new MyClass();
    // myObj->printHi(); // does not reach here

    // error: cannot bind non-const lvalue reference of type ‘MyClass&’ to an rvalue of type ‘MyClass’
    //MyClass& myObj = MyClass();
    //myObj->printHi(); // does not reach here

    return 0;
}
  •  Tags:  
  • c
  • Related