hi

please can anyone tell me the difference between virtual function and abstraction function .

Recommended Answers

All 5 Replies

A function which we think may be overloaded in the derived classes is marked with keyword virtual so as to inform the compiler that this function has a fair chance of getting overloaded in the derived classes.
A base class which has at least one pure virtual function cannot be instantiated and hence acts like an Abstract class in Java.

An abstract method (I assume this is what you mean by abstraction function) is a method that has no definition - there is a signature, but no provided implementation.

For example, if I have a file 'example.h'

class Example
{
public:
	int foo(int x, int y);
	int bar(int x, int y);
};

And a file, 'example.cpp'

#include "example.h"

int Example::foo(int x, int y)
{
	return x+y;
}

foo() is not an abstract method, because it has an implementation in addition to its signature. bar() is an abstract method, because it has a signature but no implementation.
Because it contains abstract methods, we cannot create an instance of an Example object.

A virtual function is something different.
A virtual function is declared with the virtual keyword. It means that if we are storing an object through a pointer to a class that is higher than it in its inheritance hierarchy, the call will still resolve to the actual method provided by the derived class.

As an example, given two classes:

class BaseClass
{
public:
	virtual int foo();
	int bar();
};

class DerivedClass : public BaseClass
{
public:
	int foo();
}

The following code snippet will behave as described in the comments:

BaseClass* ptr = new DerivedClass();	// Create an object of type DerivedClass, and store a reference to it using a BaseClass pointer
ptr->foo();	// Because foo() has been declared as virtual in BaseClass, the compiler will 'know' that we want to call the foo() method defined in the actual object - that is, DerivedClass::foo() and not BaseClass::foo().
ptr->bar(); // We did not declare bar() as virtual in BaseClass, so the compiler will call BaseClass::bar() even if we provide an implementation of bar() in DerivedClass.

A 'pure' virtual function is slightly different again. If we do something like:

class BaseClass
{
public:
	virtual int foo() = 0;
	int bar(int x, int y);
};

Then foo() will be a 'pure' virtual function. This means that classes derived from BaseClass will have to provide an implementation for foo() even if BaseClass has already provided one.

An abstract method (I assume this is what you mean by abstraction function) is a method that has no definition - there is a signature, but no provided implementation.

For example, if I have a file 'example.h'

class Example
{
public:
	int foo(int x, int y);
	int bar(int x, int y);
};

And a file, 'example.cpp'

#include "example.h"

int Example::foo(int x, int y)
{
	return x+y;
}

foo() is not an abstract method, because it has an implementation in addition to its signature. bar() is an abstract method, because it has a signature but no implementation.
Because it contains abstract methods, we cannot create an instance of an Example object.

A virtual function is something different.
A virtual function is declared with the virtual keyword. It means that if we are storing an object through a pointer to a class that is higher than it in its inheritance hierarchy, the call will still resolve to the actual method provided by the derived class.

As an example, given two classes:

class BaseClass
{
public:
	virtual int foo();
	int bar();
};

class DerivedClass : public BaseClass
{
public:
	int foo();
}

The following code snippet will behave as described in the comments:

BaseClass* ptr = new DerivedClass();	// Create an object of type DerivedClass, and store a reference to it using a BaseClass pointer
ptr->foo();	// Because foo() has been declared as virtual in BaseClass, the compiler will 'know' that we want to call the foo() method defined in the actual object - that is, DerivedClass::foo() and not BaseClass::foo().
ptr->bar(); // We did not declare bar() as virtual in BaseClass, so the compiler will call BaseClass::bar() even if we provide an implementation of bar() in DerivedClass.

A 'pure' virtual function is slightly different again. If we do something like:

class BaseClass
{
public:
	virtual int foo() = 0;
	int bar(int x, int y);
};

Then foo() will be a 'pure' virtual function. This means that classes derived from BaseClass will have to provide an implementation for foo() even if BaseClass has already provided one.

@Earth Wyrm : You cannot include a prototype of a function in a class and leave it undefined. Its a compiler error. You have to ground the function saying that this function is not defined. And any class which inherits from this class has to define the function so we tag it with the tag virtual. And hence its called as a pure virtual function. i,e a virtual function which has no definition (i,e is grounded).

class BaseClass
{
public:
	virtual int foo() = 0;
	int bar(int x, int y)
        {
            return x+y;
        }
};

To be honest, I'm not 100% sure I've got you right, but if you're saying what I think you're saying...
Sure you can. I mean, you probably shouldn't but it suffices for an example.
It's only a compile error if you try to use the undefined function, or instantiate the base class.

The following code compiles on VS8, with a prototype for bar() given but with no definition.

#include <iostream>

class BaseClass
{
public:
    virtual int foo() = 0;
    int bar(int x, int y);
};

class DerivedClass : public BaseClass
{
public:
    int foo(){ return 0; };
};

int main(int argc, char **argv)
{
    BaseClass* testObj = new DerivedClass();
    testObj->foo();
    //testObj->bar(0, 1);    // Compile error if uncommented. Unresolved call.
    //BaseClass baseObj;    // Will also cause a compile error. Trying to instantiate an abstract class.
    //BaseClass* baseObj = new BaseClass();    // Will also throw a compile error. Trying to instantiate an abstract class.
    DerivedClass derivedObj;
    derivedObj.foo();
    //derivedObj.bar(0, 1);    // Compile error if uncommented. Unresolved call.
    
    std::cin.get();
}

Edit:
I suppose that you may have been referring to the part:

class BaseClass
    {
    public:
        virtual int foo();
        int bar();
    };
     
    class DerivedClass : public BaseClass
    {
    public:
        int foo();
    }

In that case, the code snippet that I gave following it was illegal, but I intended for the existence of a file containing an implementation for DerivedClass::foo ()to be implied.

I found this quote to be quite nice about your topic: "An abstract function can have no functionality. You're basically saying, any child class MUST give their own version of this method, however it's too general to even try to implement in the parent class. A virtual function, is basically saying look, here's the functionality that may or may not be good enough for the child class. So if it is good enough, use this method, if not, then override me, and provide your own functionality." -BFree, StackOverflow

@csurfer>>You cannot include a prototype of a function in a class and leave it undefined. Its a compiler error.
That's wrong. Of course you can give a prototype of a function in a class and not provide an implementation for it. The linker will only look for the implementation of the function when it is called, and it will throw an "undefined reference" if you didn't provide it. Also, sometimes the function is not reachable because it is private so its implementation is not needed at all, people use this concept all the time, with the so-called "non-copyable" idiom:

class non_copyable {
  private:
    non_copyable(const non_copyable&);
    non_copyable& operator=(const non_copyable&); 
};

In the above, both the copy-constructor and assignment operator are not reachable because they are private, but the fact that they are there tells the compiler not to generate default versions of those functions. The consequence is that the class and any of its derived classes create objects that cannot be copied (which is very commonly used in practice to disable copying when it is meaningless or wrong to do so). And, of course, the implementations of the two functions are omitted because any attempt to call them will be caught by the compiler as an access-right violation before the linker has a chance to look at it and find no implementation.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.