views:

181

answers:

5

Possible Duplicate:
Calling virtual functions inside constructors

first of all below code is not working visual c++ , but workin with bloodshed

output is 0 , but acc. to me it shud be 1 ; can anyone explain this

#include<iostream>
using namespace std;
class shape
{
public:
    virtual void print() const =0;
    virtual double area() { return 0.0;}
};
class point : public shape
{
    int x;
    int y;
public :
    point(int a=11, int b=11)
    {
        x=a;
        shape *s;
        s=this;
        cout<<s->area();
        y=b;
    }
    double area()const {return 1.0;}
    void print() const
    {
        cout<<"\nPoint\n";
        cout<<x<<"\t"<<y;
    }
};

int main()
{   
    point p(1,2);
    return 0;
}
A: 

Calling a virtual function in the constructor of a function acts as if the function is not virtual. It can be confusing, but it's standard behavour in c++

If you want to achieve your aim then you should probably have an "initialise" function that you call after the constructor in which virtual function calls will work as you expect.

John Burton
Actually, this is not really confusing. If the function behaved virtually and called the derived class method, then we would be calling that method without the derived class constructor having executed first.
Tarydon
Actually, calling a virtual method during constrution is undefined behavior. The rational Tarydon puts forward is the best logical reason not to do it. From a compiler perspective it depends on how the compiler implements virtual methods (and was deliberately) left undefined by the standard to allow the compiler to be as efficient as possible. Thus different compilers do it different ways (as shown by the OP results).
Martin York
@Martin, C++ Standard 12.7p3: "Member functions, including virtual functions (10.3), can be called during construction or destruction (12.6.2)."
Johannes Schaub - litb
+3  A: 

You got the correct output. It should be 0. When you call area() in the constructor of your derived class, actually the base version of area() is called instead of the derived version. Calling a virtual function inside a constructor won't call the overriding functions in the derived classes.

Read this.

Prasoon Saurav
This answer is wrong. Notice that the FAQ says "When my base class's constructor calls a virtual function on its this object" - but in the code the call is done by the derived's class constructor.
Johannes Schaub - litb
I posted the link just to show how the given mechanism works(having a function call inside a constructor).
Prasoon Saurav
The call in the derived class should hit the derived class function if it would really override the base class function. But it doesn't because of the `const`. It has nothing to do with the constructor.
Johannes Schaub - litb
My bad, thanks for saving my life. :-(
Prasoon Saurav
This answer is WRONG. Please fix. Any call to a virtual function in the constructor/destructor has undefined behavior (as demonstrated by the caller with two different answers depending on compiler). It completely depends on how the compiler implements the virtual call mechanism. As usual the C++ FAQ lite is glossing over the details (not a good reference source).
Martin York
@Martin, C++ Standard 12.7p3 (emphasis by me): "Member functions, **including virtual functions** (10.3), can be called during construction or destruction (12.6.2). When a virtual function is called directly or indirectly from a constructor (including from the mem-initializer for a 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."
Johannes Schaub - litb
+2  A: 

Calling virtual functions from the constructor is a really bad idea. See this Calling virtual functions from constructor (see 3rd para) for details.

Naveen
Please use somthing more authoritative than the C++ FAQ lite (like the C++ standard). It (C++ FAQ Lite) is know to have lots of errors and misleading information (Though it does have some useful info).
Martin York
+3  A: 

There's a subtle flaw in your code:

double area()const {return 1.0;}

The base class' area() method is not declared const. point::area is therefore not a virtual method. Either declare shape::area const as well or remove const from point::area and it will work as expected.

Hans Passant
this looks like the problem. Because the pointer isn't a "const shape *" it won't call the const function, it will call the non const function. You must make sure the declarations are the same
Grant Peters
thanks man ... tats the problem
mayur
@mayur, you may wish to accept his answer if it helped you out.
Johannes Schaub - litb
A: 

@nobuz so just i want to clear my point . that in vtable of class point , base::area is there and not point::area as point::area is not a virtual method since this function is const while virtual base::area is not?? I think i got it right??

mayur
Awesome answer mark.
Hans Passant