Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ways to return an object in C++ method

Say I have a class that looks like this

class MyAnimals{
public:
    Animal getAnimal(int index){
        return animals.at(index);
    }
private:
    vector<Animal> animals;
}

From what I've learned about C++ so far, I think getAnimal currently returns a copy of the animal, not a reference like in Java. I've seen this suggested as the correct way to go about returning objects, but what if you want to modify that animal once it's returned? I'd just be changing the copy of it and the actual animal inside of MyAnimals.animals would remain unchanged. One way I've seen to get around this is to return Animal& instead of Animal, and that seems to work for the most part, but what if I want to reassign the variable the was assigned to that returned Animal? For example,

Animal& a = myanimals.getAnimal(1);
a = myanimals.getAnimal(2);

From what I get, this would change the animal at myanimals.animals[1] to be the same exact object as myanimals.animals[2], since a was a reference. What are the different ways to go about returning objects?

like image 869
Weston Avatar asked Jan 07 '23 12:01

Weston


2 Answers

From what I've learned about C++ so far, I think getAnimal currently returns a copy of the animal, not a reference like in Java.

Correct.

I've seen this suggested as the correct way to go about returning objects

If you intend to return a copy, then yes.

I'd just be changing the copy of it and the actual animal inside of MyAnimals.animals would remain unchanged.

Correct.

One way I've seen to get around this is to return Animal& instead of Animal, and that seems to work for the most part

Yes, references are exactly what you need for that.

but what if I want to reassign the variable the was assigned to that returned Animal?

Well, typically there is no need to do re-assign an existing reference (which is not allowed anyway). Instead of what you did, you could do:

Animal& a = myanimals.getAnimal(1);
Animal& b = myanimals.getAnimal(2);

If you for some reason need to, then use a pointer instead, to get around the limitation. You can do this even when you return a reference:

Animal* a = &myanimals.getAnimal(1);
a = &myanimals.getAnimal(2);
like image 66
eerorika Avatar answered Jan 12 '23 22:01

eerorika


I know of the following ways to return an Animal from MyAnimals.

  1. By const reference. This allows you to avoid making a copy when you need to just query the object.

    Animal const& getAnimal(int index) const;
    
  2. By reference. This allows you to modify the object inside a MyAnimals.

    Animal& getAnimal(int index);
    
  3. By value. This is the safest method to return an Animal as far as the contents of MyAnimals is concerned but is also the most inefficient.

    Animal getAnimal(int index) const;
    
  4. Provide access to the elements through iterators.

    class MyAnimals
    {
       public:
          typedef vector<Animal>::iterator iterator;
          typedef vector<Animal>::const_iterator const_iterator;
    
          iterator begin();
          iterator end;
    
          const_iterator begin() const;
          const_iterator end const;
    
          Animal getAnimal(int index){
             return animals.at(index);
          }
       private:
          vector<Animal> animals;
    };
    
like image 35
R Sahu Avatar answered Jan 12 '23 21:01

R Sahu