开发者

how functions of a not fully constructed objects are called?

开发者 https://www.devze.com 2023-04-04 23:08 出处:网络
creating an object using a constructor and along with that calling functions of object which is being constructed:

creating an object using a constructor and along with that calling functions of object which is being constructed:

class A
{
  public:
        A()
        {
        this->show();
     开发者_如何学JAVA   }   

        void show()
        {
        cout<<"show called!";
        }
};

and now i m creating object in main() as below:

int main()
{
    A a;
    int xy;
    cin>>xy;
    return 0;
}

my doubt is that when i am creating an object using constructor then how i am able to call object function while object is not fully constructed?

virtual function calls:

class A
{
  public:
        A()
        {

        }   

       virtual void show()
        {
        cout<<"show called!";
        }
};
class B:public A
{
      public: 
              B()
              {
                    A *a=this;
                    a->show();

                    }
             void show()
             {
                  cout<<"derived show";
                  }

      };


int main()
{
    A a;
    B b;
    int xy;
    cin>>xy;
    return 0;
}

working fine with output: derived show


It's fine to call virtual functions and non-static member functions:

See section 12.7 of http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf:

4 Member functions, including virtual functions (10.3), can be called during construction or destruction (12.6.2).

However when using virtual functions in a constructor there are some restrictions. It's a bit of a mouthful:

When a virtual function is called directly or indirectly from a constructor (including the mem-initializer or brace-or-equal-initializer for a non-static data member) or from a destructor, and the object to which the call applies is the object under construction or destruction, the function called is the one defined in the constructor or destructor’s own class or in one of its bases, but not a function overriding it in a class derived from the constructor or destructor’s class, or overriding it in one of the other base classes of the most derived object (1.8).

I interpret the above paragraph as saying the virtual functions called will not be in any derived class. This makes sense because at this point in the execution phase any constructor in a derived class will not have begun execution.

Additionally part 1 places a restriction that use of non-static members should occur after the construction begins. In your example the members are being invoked after the construction begins, so you're not violating part 1:

1 For an object with a non-trivial constructor, referring to any non-static member or base class of the object before the constructor begins execution results in undefined behavior.


This code is completely legal. You can call methods in the class constructor.

All constants (from the initialization list) are already initialized and all base class constructors are called.

However, You should not call virtual methods in the constructor. See Scott Meyers explanation for this restriction.


The thing to think about is, which parts of the object are constructed at the time when you call show()?

Since you call show() from within your constructor's body (and not e.g. from within the constructor's initializer list) you can rest assured that all of the A object's member variables have already been constructed (since that happens before the constructor body is executed).

What might trip you up would be if show() was a virtual method, and A::A() was being called from the constructor of a subclass of A. In that case, you might want show() to call B::show(), but that won't happen because the vtable for B hasn't been set up yet (you would end up calling A::show() instead, or crashing the program if A::show() was a pure-virtual method)


You are calling a function in an partially constructed object, which may result in erroneous behavior if such function deals with class members and such. I am not sure whether its invoking undefined behaviour or not, but I don't think its a good practice. And the situation gets worse with inheritance and virtual functions!

In your example, show could be declared static and there will be no risk in calling it.


Consider a class as 2 separate parts: The object containing fields (variables) and the methods (functions). The methods of a given class exist independent of any particular instance, so it can be called at any time by a valid instance, even mid-construction.

The fields are "created" when the object is instantiated, before the constructor is run. However, they have no values set to them. So, if your constructor calls any methods BEFORE the fields are initialised to sensible values, then you're going to experience some undefined behaviour.

Whenever possible, if you must call a method inside a constructor, be sure to initialise as many fields as possible to sensible values.


my doubt is that when i am creating an object using constructor then how i am able to call object function while object is not fully constructed?

what happens in your example is fine, as long as you initialize where you are supposed to (the initialization list). you are using static dispatch on an object which has initialized members (specifically, A has no such variables to initialize).

what then is invalid?

  • not initializing your members correctly, or using them before they are really initialized. favor the initialization list without using this.
  • using dynamic dispatch from within your constructor's body (or initializer). your object is not fully constructed.
  • unusually, you could also attempt to typecast it to a subclass from the constructor.
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号