Fancypants753
Fancypants753

Reputation: 449

c++ references to heap objects?

I have the below bit of code:

map<int,int>& myMap = new map<int,int>();

but I get the following compiler error:

no suitable constructor exists to convert from "std::map<int,int, std::less<int>, std::allocator<std::pair<const int, int>>>*" to "std::map<int,int, std::less<int>, std::allocator<std::pair<const int, int>>>".

Does this mean I have to do:

map<int,int>& myMap = *new map<int,int>();

I thought that objects could passed to references without dereferencing first (as opposed to pointers)? Also I know smart pointers exist but I'm not trying to use those for now.

Upvotes: 1

Views: 4302

Answers (2)

Slava
Slava

Reputation: 44258

I thought that objects could passed to references without dereferencing first (as opposed to pointers)?

Yes objects can be passed, but what you have here:

map<int,int>& myMap = new map<int,int>();

is not an object but reference which you try to initialize by pointer to dynamically allocated object. Just create object:

map<int,int> myMap;

and it should work fine.

To make things clear, you mixed different concepts, lets say we have a function that accepts variable of sometype by reference:

void func( sometype &ref ) { ... }

it does not mean you have to declare variable as reference to pass it there, you can pass automatic object:

 sometype auto_object;
 func( auto_object );

or pass dynamically allocated one:

 sometype *ptr_to_object = new sometype;
 func( *ptr_to_object );
 delete ptr_to_object; // or better use smart pointer

and if you do not need this object to outlive scope where you use it it is preferable to use first variant.

Upvotes: 2

R Sahu
R Sahu

Reputation: 206607

You can use

map<int,int>& myMap = *new map<int,int>();

but I don't recommend it.

The dynamically allocated memory has to be deallocated. At that time, you will need to use something along the lines of

delete &myMap;

That is poor quality code, IMO.

Use a smart pointer if you need dynamically allocated memory.

std::shared_ptr<map<int,int>> ptr = new map<int,int>();

If you need to use a reference, you can use:

map<int,int>& myMap = *ptr;

It will better if you can avoid dynamically allocated object altogether and use an automatic object (object in stack memory).

map<int,int> myMap;

Update, in response to OP's comment

In a comment you said

Yeah i want to keep that reference because im passing it to a recursive function

The C++ way to deal with it is to pass an object by reference.

void recursive_foo(std::map<int, int>& myMap)
{
}

void foo_user()
{
   std::map<int, int> myMap;
   // Fill up myMap
   // ...

   recursive_foo(myMap);
}

If the recursive function does not modify the object, you can follow the idiom used by the standard library and use iterators instead.

void recursive_foo(std::map<int, int>::iterator start,
                   std::map<int, int>::iterator end)
{
}

void foo_user()
{
   std::map<int, int> myMap;
   // Fill up myMap
   // ...

   recursive_foo(myMap.begin(), myMap.end());
}

Upvotes: 8

Related Questions