`

c++ - vritual function and default arguments

    博客分类:
  • c++
c++ 
阅读更多

As we all know that we virtual function does not overload an existing function, but rather it reuse the same member method and the right method to be invoked is determined at runtime.

 

 

So, here is the problem since we all know that for a given function, you can only define one set of default argument, but the potential number of virtual function (the base virtual function, the derived ones) could be infinite. 

 

Does it mean we cannot redefine the default argument ? With this restriction, there is a predicament.  What if you are extending some libraries code, and the libraries code has some default value, while you are taken away the right to provide a more appropriate value for you class. so what is the default argument when virtual function is invovled?

 

the misunderstood way

 

/**
* file
*  virtual_function_default_arguments.h
* description:
*  this file demonstrate the use of default argument when the virtual function are considered
*
*/

#include <iostream>

using std::cout;
using std::cerr;
using std::endl;


class base
{
public:
	virtual int foo(int ival = 1024) {
		cout << "base::foo() -- ival: " << ival << endl;
	}

};



class derived : public base
{
public:
	virtual int foo(int ival =2048) {
		cout << "derived:foo() -- ival: " << ival << endl;
	}

}

 

 

The result turns that it does not work out the way we expected.

 

As you can see from the output, the default value applied is determined through the the invoker, could it be the pointer, or the reference. So that if you invoke through derived *, then the default argument value of derived version is used. Should you use the base *pointer, the default arguments value of the base classes is choosen. So in nutshell, the value of defaulot argument is not determined at runtime, but rather at compile time.

 

/**
* file
*  virtual_function_default_arguments.cpp
* description:
*  this file demonstrate the use of default argument when the virtual function are considered
*
*/

#include "virtual_function_default_arguments.h"


/**
*  void virtual_function_default_arguments()
*  
* as you can see from the output, the default value applied is determined through the the invoker, could it be the pointer, or the reference.
* so that if you invoke through derived *, then the default argument value of derived version is used. 
* should you use the base *pointer, the default arguments value of the base classes is choosen.
* 
* so in nutshell, the value of defaulot argument is not determined at runtime, but rather at compile time.
*/
void virtual_function_default_arguments()
{
	derived * pd =  new derived;
	base *pb = pd;

	int val = pb->foo();
	cout << "main(): val through base: "
		<< val << endl;

	val = pd->foo();
	cout << "main() : val through derived" 
		<< val << endl;
}

 

 

The right way

 

To use the default value with virtual functio has farreaching meaning, the runtime nature of virtual function and the static nature of default argument does not fit in well with each other. however, if you do want to have default argument with virtual function, instead of simply saying no, you can provide some place holder value which indicate that no value has been passed by the user as shown in the code below.

 

 

 

class base
{
public:
	const base_default_value = -1; 

	virtual int bar(int ival  = base_default_value) {
		int real_default_value = 1024;
		if (ival == base_default_value) {
			ival = real_default_value;
		}

		cout << "base::foo() -- ival: " << ival << endl;
	}

};



class derived : public base
{
public:
	virtual int bar(int ival = base_default_value) {
		int real_default_value = 2048;
		if (ival == base_default_value) {
			ival = real_default_value;
		}

		cout << "base::foo() -- ival: " << ival << endl;
	}
}
 

 

and below shows the code that demon how to use it.

 

 

 

/**
*  void virtual_function_default_arguments2()
*  
* to use the default value with virtual functio has farreaching meaning, the runtime nature of virtual function and the static nature 
* of default argument does not fit in well with each other. however, if you do want to have default argument with virtual function
* instead of simply saying no, you can provide some place holder value which indicate that no value has been passed by the user
* as shown in the code below.
*/
void virtual_function_default_arguments2()
{
	derived * pd =  new derived;
	base *pb = pd;

	int val = pb->bar();
	cout << "main(): val through base: "
		<< val << endl;

	val = pd->bar();
	cout << "main() : val through derived" 
		<< val << endl;
}
 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics