is 'giving out' a reference to 'this' inside the constructor ok?
my code :
Scene::Scene(const std::string &scene_file) : ambient_light(0, 0, 0), background(0, 0, 0){
scene_parser parser(*this);
parser.parse(scene_file);
}
scene_parser is a friend of Scene, and in the parse method it accesses(r/w) the members of Scene. Is this going to cause any problem开发者_如何学Gos?
Yes, it's ok to give out a reference to this
. However, you usually want to do that when the other object will use the pointer later. Your use case looks like it will use the Scene
immediately, before the constructor completes, which is a very slippery slope.
Right now, you're not establishing any invariants after calling parse
, so it should be ok, but it's also fragile and easy for future changes to introduce breakage.
In your particular example, no problems should arise.
Generally the problem with giving out this
references is that the lifetimes of the two objects don't exactly align and the other object could try to access the referred-to object after it has already been destroyed.
In your example, the scene_parser
object is on the stack, so it's lifetime ends at the end of the Scene
constructor. There is no possible way it could attempt to access a non-existent object via that this
reference you provided, so no problems can arise.
It depends.
Inside the constructor body (i.e. once the initializer list is executed), the object is considered "fully constructed" up to the current type. Therefore, you can reference *this
, but any virtual
function calls will not use overrided functions in derived classes.
All of your subobjects (members and bases) are constructed by the first statement in the body of the constructor. If your object is in a "valid state" (which is part of the definition of your class, sometimes called the "class invariant") at this point, you can treat it as a fully constructed object and do anything with it. However, virtual lookup does work slightly differently than you may expect or require: if this is a base class (and thus this object is a subobject of something else), the final type hasn't been "assigned" yet. For example, this is one way to call pure-virtual methods and get a runtime error (if those methods don't have definitions, anyway).
A more interesting situation is using this in the constructor initializer; that does have some caveats, but that is also before the constructor body.
精彩评论