What is the difference between Friend Function and virtual function?

suchi's Avatar, Join Date: Jul 2009
Newbie Member
Could somebody help me out to point out Difference Between Friend Function and virtual function. I am very much confuse with the definition and use of both also.
xpi0t0s's Avatar, Join Date: Aug 2004
They're completely different beasts...

A friend function is a function that can access a class's private members while not being a member of that class. (You can also have friend classes)

A function is defined virtual so that polymorphism can work: if you have a pointer to the base class and invoke a virtual function, the derived class's version of the function is called. Without virtual functions you would have to cast a pointer to a base class to a pointer to a derived class to invoke the intended function.

class base
	virtual void foo() { printf("Base class foo()\n"); }
	void bar() { printf("Base class bar()\n"); }

class c : public base

	void foo() { printf("c foo()\n"); }
	void bar() { printf("c bar()\n"); }

	friend c *friend_func();

c *friend_func()
	return new c;

void fvtest()
	// c my_c; // compile error due to private constructor
	base *b=friend_func();
	b->foo(); // should call c::foo()
	b->bar(); // should call b::bar()
	c* cptr=(c*)b;
	cptr->foo(); // should call c::foo()
	cptr->bar(); // should call c::bar()
(In my testbed main just calls fvtest())

c foo()
Base class bar()
c foo()
c bar()

So you see here that b is defined as a pointer to base, is used as a pointer to base, but a pointer to c action occurs because b::foo() is virtual. b::bar() is not virtual so b->bar() invokes b::bar().

Also you can see that no cast is needed where b is initialised, i.e. you don't have to say base *b=(base*)friend_func(). This is because it's perfectly OK to assign a pointer-to-derived to a pointer-to-base variable. On the other hand a cast IS needed to initialise cptr, because an object that is pointed to by a base pointer might not actually be of class c. So this assignment is unsafe and a cast is required, but that's OK because we know friend_func() returned a c*.

If you actually want to call base::foo() directly, using b, then you have to specify the class: