0
class Test
{
public:
    typedef std::map<double, double> MapType;

private:
    MapType myMap;
 public:
    ...
    const MapType& getMap() const  // is this normal????
    {
        return myMap;
    }
};

I would like to use my Map outside of the class Test, can I return the reference or there are some bad cases?

billz
  • 44,644
  • 9
  • 83
  • 100
Vardan Hovhannisyan
  • 1,101
  • 3
  • 17
  • 40
  • yes, you can. but this is not big question – AnatolyS Sep 25 '13 at 10:41
  • Perfectly fine unless the `Test` class object itself is destroyed. – sharptooth Sep 25 '13 at 10:42
  • If you don't want `myMap` to be changed from outside of your class it's a good idea to make a defencive copy – SpongeBobFan Sep 25 '13 at 10:42
  • @SpongeBobFan Returning `const` would prevent modification just fine (although, since this is C++, the caller can probably just cast a pointer to the reference to non-const and modify it, but you can't cater for everything). – Bernhard Barker Sep 25 '13 at 10:46
  • 2
    In the spirit of encapsulation, you should think twice about whether you really want to expose your map to the outside. But if you really do, this way is fine. – Sebastian Redl Sep 25 '13 at 10:59

3 Answers3

1

It's perfectly OK in most cases (however return by value is preferred, if your type is not big). There is only one bad case, when your object will be destroyed - your reference on map will be dangling.

Example of this case:

const Test::MapType& getNewMap()
{
   return Test().getMap();
}

// somewhere in code

const Test::MapType& map = getNewMap();
ForEveR
  • 55,233
  • 2
  • 119
  • 133
  • Return by value is preferred? Creating unnecessary copies of big objects really doesn't seem like the preferred way. – Bernhard Barker Sep 25 '13 at 10:50
  • @Dukeling If the user wants a return by value they can just catch by value. This even works with C++11 `auto`. So I'd argue you still get the default return-by-value, but if the user explicitly wants to shoot themself in the foot (catch by reference) you let them. – ComicSansMS Sep 25 '13 at 10:56
  • @Dukeling it depends on your task. for example if you will use map to find key there, it is one task and in this case you have to add only one member function find instead of the map returing. – AnatolyS Sep 25 '13 at 10:58
1

In my eyes, this is fine.

If the user catches the return value by value she will get a copy anyway. If it is catched by reference, it should be obvious that the reference is not supposed to outlive the object that returned it.

ComicSansMS
  • 51,484
  • 14
  • 155
  • 166
0

If all you want is to see the contents, return a copy of the type - the compiler will optimize any overhead in copying large types.

    const MapType getMap() const
    {
        return myMap;
    }
  • How do you convert MapType to std::shared_ptr in the fly? – billz Sep 25 '13 at 10:53
  • Note that it may make no sense for the data member to stay alive after the object that contains it dies. This is a solution for a very specific case. – juanchopanza Sep 25 '13 at 10:59
  • @billz - I'd assume that using `make_shared` with an existing MapType will use the copy constructor to initialize a new MapType. – The Forest And The Trees Sep 25 '13 at 11:08
  • This is ill advice in general, it seems you haven't even heard of [initialization](http://stackoverflow.com/q/1711990/140719) [lists](http://stackoverflow.com/q/1242830/140719), and you attempt to return a non-const reference to an object from a const member function. That's pretty much as `-1` as it can get. – sbi Sep 25 '13 at 11:23
  • @sbi: You're right, I'm not sure what I was thinking here with allowing him to update it when it clearly needs to keep const-correctness. I've updated it to remove that. – The Forest And The Trees Sep 25 '13 at 12:35
  • 1
    Returning by const value is not that much better either. See e.g. [Lavavej's GoingNative 2013 talk](http://channel9.msdn.com/Events/GoingNative/2013/Don-t-Help-the-Compiler) (at about 0:35:00). – ComicSansMS Sep 25 '13 at 13:22