Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Virtual Functions and Polymorphism

59 views
Skip to first unread message

Bilal

unread,
Apr 26, 2017, 8:26:07 PM4/26/17
to
Hello everyone,

I am newbie, so please bear with my post.

I recently studied about 'virtual functions' (particularly in c++) and ran a couple of example codes successfully. I understood that 'virtual function' declared with virtual keyword is a member function of a class that can be overridden in its derived class.

The above information/definition is more than enough for me to start using virtual functions for my purpose.

However, some of the definitions available on internet are confusing. For example, over a dozen of web resources say "Virtual function call is resolved at run-time (dynamic binding) whereas the non-virtual member functions are resolved at compile time (static binding)".
I read about the second definition from a dozen of books/internet resources and all of them keep iterating the same 'early/late binding' things. Just wondering how much is it useful to know the second definition for a future programmer/instructor.

Finally, is it possible that a virtual member function call is resolved at compile-time and not at run-time.

Thanks
-Bilal

Jerry Stuckle

unread,
Apr 26, 2017, 8:48:46 PM4/26/17
to
It is an important concept to understand.

Virtual functions come into play when you have a pointer or reference to
an object. When that is the case, the pointer or reference may be of
the type base_class, but the actual object could be be of type
derived_class.

For instance, say you have a function

class base_class {
public:
virtual void vf();
};

class derived_class_1 : public base_class {
public:
virtual void vf();
};

class derived_class_2 : public derived_class_1 {
public:
virtual void vf();
};

void f(base_class& br) {
br.vf(); // Could call any of the virtual functions vf()
}

You could call it with

base_class b;
derived_class_1 d1;
derived_class_2 d2;
f(b);
f(d1);
f(d2);

The compiler can't tell at compile time which it is, so it cannot
predict which function will be called ; this must be done at run time -
and is the basis of virtual functions.

However, this is only if you have a pointer or reference - if you have
the real object, the compiler can tell which function to call:

b.vf(); // calls base_class::vf();
d1.vf(); // calls derived_class_1::vf();
d2.vf(); // calls derived_class_2::vf();

Hope this helps. Kinda hard to explain in a newsgroup post. Much
easier with a whiteboard :)

--
==================
Remove the "x" from my email address
Jerry Stuckle
jstu...@attglobal.net
==================

Daniel

unread,
Apr 26, 2017, 9:52:47 PM4/26/17
to
On Wednesday, April 26, 2017 at 8:48:46 PM UTC-4, Jerry Stuckle wrote:
>
> The compiler can't tell at compile time which it is, so it cannot
> predict which function will be called ; this must be done at run time -
> and is the basis of virtual functions.
>
Actually, sometimes the compiler can tell, and can devirtualize the function at
compile time, particularly if the author of a class uses the final keyword.

Daniel

Ian Collins

unread,
Apr 26, 2017, 10:32:39 PM4/26/17
to
On 04/27/17 12:25 PM, Bilal wrote:
> Hello everyone,
>
> I am newbie, so please bear with my post.
>
> I recently studied about 'virtual functions' (particularly in c++)
> and ran a couple of example codes successfully. I understood that
> 'virtual function' declared with virtual keyword is a member function
> of a class that can be overridden in its derived class.
>
> The above information/definition is more than enough for me to start
> using virtual functions for my purpose.
>
> However, some of the definitions available on internet are confusing.
> For example, over a dozen of web resources say "Virtual function call
> is resolved at run-time (dynamic binding) whereas the non-virtual
> member functions are resolved at compile time (static binding)". I
> read about the second definition from a dozen of books/internet
> resources and all of them keep iterating the same 'early/late
> binding' things. Just wondering how much is it useful to know the
> second definition for a future programmer/instructor.

It's a very useful concept to grasp.

With static/early binding the compiler always knows the the function to
call and can embed the function's address directly in the generated
code. Because it always knows the function to be called, it can, if
conditions are right, inline the function body and avoid a call.

> Finally, is it possible that a virtual member function call is
> resolved at compile-time and not at run-time.

Yes - if the compiler can determine which function will be called.

--
Ian

Jerry Stuckle

unread,
Apr 26, 2017, 11:13:04 PM4/26/17
to
An example? I have yet to see such a case.

Tim Rentsch

unread,
Apr 27, 2017, 9:41:58 AM4/27/17
to
Jerry Stuckle gave a pretty good answer. The only thing I
would add is about compile-time vs run-time resolution.

For virtual functions this distinction is purely one of
performance improvement, ie, a so-called "optimization", but
otherwise makes no difference; that is, the program will
behave the same way whether the resolution is done at
run-time or compile-time, not counting any difference in how
fast it would run. As with most micro-scale performance
improvements, generally it is not worth worrying about, and
that is especially true for you since you are just starting
up the learning curve.

Alf P. Steinbach

unread,
Apr 27, 2017, 2:13:44 PM4/27/17
to
On 27-Apr-17 2:25 AM, Bilal wrote:
> [snip] Finally, is it possible that a virtual member function call is
> resolved at compile-time and not at run-time.

In two cases:

• You have turned off the virtual mechanism for a specific call by
qualifying the function name with the class where the particular
implementation you want, is (or is available by inheritance), e.g.
`obj.My_class::foo()`. This is a non-virtual call of a virtual member
function.

• The compiler has determined, for a particular virtual call, that (1)
it knows which implementation the virtual call mechanism would end up
executing, and (2) that it can shave off a nanosecond or two by calling
that implementation directly, or even inlining the function code.


Cheers & hth.,

- Alf

Juha Nieminen

unread,
May 2, 2017, 3:12:40 AM5/2/17
to
Bilal <bilal...@googlemail.com> wrote:
> However, some of the definitions available on internet are confusing.
> For example, over a dozen of web resources say "Virtual function call
> is resolved at run-time (dynamic binding) whereas the non-virtual
> member functions are resolved at compile time (static binding)".

The simplest explanation is an example:

//------------------------------------------------------
class Base
{
public:
void func1() const { std::cout << "func1\n"; }
virtual void func2() const = 0;
};

void foo(Base& obj)
{
obj.func1(); // Can be resolved at compile time
obj.func2(); // (Probably) resolved at runtime
}
//------------------------------------------------------

In the first case the compiler can see directly which function
implementation is being called, so it can put a direct function
call there (or even inline the implementation, if it sees it).

In the second case the compiler (usually) cannot know which
implementation will be called, so it uses some runtime logic
to find out. In practice this is just an indirect function call,
which isn't much heavier than a direct one.

(In most/all compiler implementations there's a point at the beginning
of 'obj' pointing to a static table created by the compiler, and at some
specific offset there will be a function pointer that the compiler
uses to make the function call. Each derived class will have its
own such virtual table, and objects of that type will have that
vtable pointer pointing to it.)

An usage example would be:

//------------------------------------------------------
class Derived1: public Base
{
public:
virtual void func2() const { std::cout << "derived1\n"; }
};

class Derived2: public Base
{
public:
virtual void func2() const { std::cout << "derived2\n"; }
};

int main()
{
Derived1 obj1;
Derived2 obj2;
foo(obj1); // will print "derived1"
foo(obj2); // will print "derived2"
}
//------------------------------------------------------

> Finally, is it possible that a virtual member function call is
> resolved at compile-time and not at run-time.

It's theoretically possible, but it doesn't affect the behavior of
the program in any way.
0 new messages