2

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;
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
mayur
  • 29
  • 3
  • 2
    duplicate, see e. g. http://stackoverflow.com/questions/962132/calling-virtual-functions-inside-constructors – just somebody Jan 03 '10 at 13:50
  • i voted for reopen. This is not an exact duplicate. The question has a problem with const/nonconst overriders, and the call is not happening in a constructor of the baseclass (as opposed with the linked "duplicate"). The answers claiming any constructor problems are plain wrong. same problem happens if in main you do `cout << ((shape*)&p)->area();` – Johannes Schaub - litb Jan 06 '10 at 18:58

4 Answers4

3

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.

Adrian
  • 5,603
  • 8
  • 53
  • 85
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
2

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

Naveen
  • 74,600
  • 47
  • 176
  • 233
  • 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 Jan 03 '10 at 17:53
  • Effective C++ agrees w Naveen :) – Adrian Jan 05 '12 at 21:45
0

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.

jcoder
  • 29,554
  • 19
  • 87
  • 130
  • 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 Jan 03 '10 at 14:02
  • 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 Jan 03 '10 at 17:50
  • @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 Jan 03 '10 at 18:27
-2

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
  • 91,295
  • 49
  • 239
  • 345
  • 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 Jan 03 '10 at 15:12
  • I posted the link just to show how the given mechanism works(having a function call inside a constructor). – Prasoon Saurav Jan 03 '10 at 15:47
  • 1
    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 Jan 03 '10 at 15:53
  • 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 Jan 03 '10 at 17:44
  • 2
    @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 Jan 03 '10 at 18:20