Anshul garg
Anshul garg

Reputation: 233

Virtual Function c++

Hi i have 1 question regarding c++ virtual function...

class base{
 public :
    base()  { a=5;}
    int a;
    virtual void print()=0;
    int get(){return a;}
    int get_var(){ a=5;  return a;}
};  

int main(void){
    base *p;
    cout <<"Get Call - No assign\n";
    cout <<"Value is :: "<<p->get()<<endl;
    cout <<"Get Call - assign value\n";
    cout <<"Value is :: "<<p->get_var()<<endl;
    return 0;
}

Its o/p is :: Get Call - No assign Value is :: 5 Segmentation Fault

I don't understand this behaviour ?
One reason i can think is - as base is abstract class i.e. not having complete implementation so when i am doing a=5 its getting crashed.
but in first call also i am using a so why it is not getting crashed there
Please help....

Upvotes: 0

Views: 162

Answers (4)

Alok Save
Alok Save

Reputation: 206616

Root Cause:

Your pointer p does not point to any valid object and hence the crash(actually it is an Undefined Behavior) when you derefence it by calling a member function on it.

When you declare a pointer just points to any random address, it your responsibility to make it point to a valid object to be able to do anything meaningful with the pointer.

Solution:

You need:

base *p = new base; 

or

base obj;
base *p = &obj;

For either of the above to work, base has to be non-abstract class.In your example base is an abstract class(class with at-least one pure virtual function), for such an class you cannot create any objects of it(call its constructor).
So to resolve this problem you need to create a Derived class which derives from your abstract class base and then implement the pure virtual function print() for your derived class thus making your derived class a concrete class and not an abstract class. Then you can check out the dynamic dispatch at work(I am guessing that was your aim)

class Derived:public base
{
    public:
        virtual void print()
        {
            //Do some prints
        }
};

int main()
{
    Derived obj;
    Base *ptr = &obj;

    //or

    Base *ptr2 = new Derived;

    //.....Rest of your program as is
}

Upvotes: 3

hmjd
hmjd

Reputation: 122001

One reason i can think is - as base is abstract class i.e. not having complete implementation so when i am doing a=5 its getting crashed.

No, the crash is caused by dereferencing the unitialised pointer p (technically undefined behaviour). As base is abstract there is no way to create an instance of it:

base b;             // Illegal
base* p = new base; // Illegal 

and there are no derived concrete classes in the posted code. You need to derive from base and implement the pure virtual function print(). The destructor in the base class should also be virtual.

Upvotes: 1

aschepler
aschepler

Reputation: 72431

p is an uninitialized pointer. So doing almost anything with it is Undefined Behavior.

And the answer to "why didn't it crash earlier" is usually "luck" (good or bad, depending on your view). A program with Undefined Behavior is allowed to do anything at all: seem to work, crash, make your mouse explode, etc.

Upvotes: 0

Andriy
Andriy

Reputation: 8604

You didn't initialize base *p;, therefore calling methods on it is Undefined Behavior (a segfault in your case).

On the other side, it would not be possible to initialize it because base is an abstract class. You must provide a definition of print in base or in a derived class.

Upvotes: 2

Related Questions