0

I have a std::vector with objects of the class Actor

std::vector<Actor>  actors(9);

I need to create a method which takes a single input parameter. The method should find the right Actor object in the Vector and return a reference to it. This reference will later be used by the callee to update the Object. I've tried to do this through

Actor& get_actor_ref_from_ped(Ped ped) {
    for (int i = 0; i < actors.size(); i++) {
        if (actors[i].isActorThisPed(ped)) {
            return actors[i];
        }
    }
    /* same issue with this approach
    for (auto &actor : actors) {
        if (actor.isActorThisPed(ped)) {
            return actor;
        }
    }*/
    //return null Actor
    return Actor::Actor();
}

However, when I try to update the Actor reference from another object, it behaves as if it was copied by value. Here is an example code. actor.hasSpotLight() is 1, but all vectorActor.hasSpotLight() are 0

void action_next_spot_light() {
    Actor actor = get_actor_ref_from_ped(PLAYER::PLAYER_PED_ID());
    if (actor.isNullActor() == false) {
        if (actor.hasSpotLight()==false) {
            actor.setHasSpotLight(true);
            log_to_file("actor.hasSpotLight() after " + std::to_string(actor.hasSpotLight()));
            for (auto &vectorActor : actors) {
                log_to_file("vectorActor.hasSpotLight() after " + std::to_string(vectorActor.hasSpotLight()));
            }
        }
    }
}

What am I missing?

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
dparnas
  • 4,090
  • 4
  • 33
  • 52

1 Answers1

6
Actor actor = get_actor_ref_from_ped(PLAYER::PLAYER_PED_ID());

Is going to make a copy of the value returned from the function as it calls the copy constructor. If you want to capture the reference you need to declare a reference.

Actor & actor = get_actor_ref_from_ped(PLAYER::PLAYER_PED_ID());
      ^^^^^^^ reference variable

You also have undefined behavior in your function when you do not find an object. return Actor::Actor(); is returning a object that is being destroyed when the function exits. If you want to return a empty object you could create a static object in the function and then return that as it will still exist. For more information on why you can't return a temporary see: Can a local variable's memory be accessed outside its scope?

Another option would be to return an iterator to the element and if no element is found then return actors.end(). Then in your caller you would check if the returned iterator is equal to actors.end(). This would require some rewrite.

Community
  • 1
  • 1
NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • Thank you.. was about stare myself blind at my own code and the various examples on the net – dparnas Oct 08 '15 at 19:40
  • so what would the best way of returning a null Actor from the method be? – dparnas Oct 08 '15 at 19:44
  • I don't understand why the OP does not get `invalid initialization of non-const reference of type 'Actor&' from an rvalue of type 'Actor'` or `error C2440: 'return' : cannot convert from 'Actor' to 'Actor &' A non-const reference may only be bound to an lvalue`. – Christian Hackl Oct 08 '15 at 19:56
  • @ChristianHackl they could be using VS which does allow this: http://stackoverflow.com/questions/16380966/non-const-reference-bound-to-temporary-visual-studio-bug – NathanOliver Oct 08 '15 at 19:57
  • @NathanOliver: Yes, if you don't use `/Za`. Which has other drawbacks. Oh well... – Christian Hackl Oct 08 '15 at 19:59
  • @ChristianHackl yes, I'm using VS – dparnas Oct 08 '15 at 20:27