Аргументи по подразбиране
(Default Arguments)
Аргументите на функции по подразбиране подобно на презаредените функции са друго удобство в C++. Подобно на тях, те позволяват да се използват по-малко на брой имена на функции. Но за разлика от презаредените функции, които на практика са няколко различни функции (въпреки еднаквото им име), то при функцията с аргументи по подразбиране имаме само една функция.
1. Пример за аргументи по подразбиране. Нека разгледаме програмата overfun.cpp от т. 3 на предишната лекция. Целта на тази примерна програма беше да се отпечатва текст на екрана по три различни начина. За целта бяха написани цели три презаредени функции - void box_display(), void box_display(char ch) и void box_display(char ch, int n).
Сега ще видим, че с аргументите по подразбиране ще напишем само една функция, която върши тези три задачи в зависимост от броя аргументи, които и се подават. По-долу е даден кодът на програмата.
//
overfun_def.cpp
//
default argument function instead of oberloaded functions
#include
<iostream.h>
#include
<string.h>
// for strcpy()
#include
<conio.h>
// for getch()
const int MAX_LENGTH = 40; // maximum length of text
class
fancy_text
// class displays text
{
private:
char text[MAX_LENGTH]; // text
to be displayed
public:
void set_text(char tx[]) // set the text
{
strcpy(text, tx);
}
// default line of MAX_LENGTH dashes
// or line of MAX_LENGTH other symbols
void box_display(char ch = '-', int n = MAX_LENGTH);
};
//
line of n characters
//
no default arguments are given in the definition
void
fancy_text::box_display(char ch, int n)
{
int j;
for (j = 0; j < n; j++)
cout << ch;
cout << endl << text << endl;
for (j = 0; j < n; j++)
cout << ch;
}
void
main()
{
fancy_text ft1;
ft1.set_text("Gone with the Wind");
// display text with default lines
ft1.box_display();
cout << endl << endl;
// default length and equal signs
ft1.box_display('+');
cout << endl << endl;
// equal signs; length matches text
ft1.box_display('=', 18);
cout << endl << endl;
getch();
} // main()
Декларацията на функцията в класа е следната: void box_display(char ch = '-', int n = MAX_LENGTH);. Разликата с една типична декларация е че има два оператора за присвояване (знаците равно) и след тях са стойностите по подразбиране, които се дават на аргумента, ако той се изпусне. В случая тези стойности са тире и константата MAX_LENGTH.
Дефиницията на функцията е извън обекта и в нея не са дадени аргументите по подразбиране. Ако тази дефиниция я напишете с аргументи по подразбиране, то компилаторът на Борланд Билдер дава следното съобщение:
Default argument value redeclared for parameter 'ch'.
В главната функция на програмата има три извиквания на функцията box_display от обекта ft1 - първото, ft1.box_display();, извиква функцията без никакви аргументи и затова тя използва и двата аргумента по подразбиране, т.е. ch е '-' и n е MAX_LENGTH. При второто извикване, ft1.box_display('+');, само за броя символи се използва аргумент по подразбиране, чиято стойност е тази в декларацията - MAX_LENGTH. Третото извикване е като извикването на обикновена функция - дадени са стойностите и на двата аргумента.
Както се разбира от този пример, можем да изпуснем най-десния аргумент или двата аргумента. Тогава при изпуснат аргумент функцията работи със стойността на аргумента по подразбинане. Разбира се, не може да се изпусне аргумент, който е отляво (т.е. преди) аргумент, на който се дава стойност. Т.е. не можем да извикаме функцията по следния начин: ft1.box_display(67);, като се надяваме, че компилаторът ще разбере, че изпускаме стойността на ch и функцията ще работи с аргумента по подразбиране '-', а ще използва n = 67.
! Тази грешка е подобна на грешката, описана в края на предишната лекция. Отново компилаторът ще помисли числото (в случая 67) за пореден номер на символа и ще изпише MAX_LENGTH на брой такива символи (в случая символът с пореден номер 67 в кодовата таблица е C).
Казано по-общо, само аргументите в края на списъка могат да имат стойности по подразбиране и компилаторът замества със стойностите по подразбиране от дясно на ляво в този списък: т.е. може да се изпусне последния аргумент, или последния и предпоследния и т.н. до всички аргументи. По същия начин не можем да декларираме по средата някой от аргументите да е по подразбиране - например първата декларация по-долу е грешна:
void badfunc(int, int=2, int); // no good
void okfunc(int, int=2, int=10); // ok
Изходът на програмата (даден по-долу) е като този на предната програма от предишната лекция - няма как и да е друг, защото сме променили само класа като сме си поставили същата задача, а извикването на функцията с аргументи по подразбиране в главната функция е същото като в предната програма overfun.cpp.
----------------------------------------
Gone
with the Wind
----------------------------------------
++++++++++++++++++++++++++++++++++++++++
Gone
with the Wind
++++++++++++++++++++++++++++++++++++++++
==================
Gone
with the Wind
==================
2. Една библиотечна функция с аргументи по подразбиране (The cin.getline() Function). В една от предишните лекции се запознахме с функцията cin.get(), която взима текст от клавиатурата. Функцията cin.getline() е подобна - например с нея може да се вземе текст до 80 символа и той да се присвои на променливата str:
cin.getline(str, 80); // get up to 80 chars, place in str
Кагото се използва по този начин, за да се присвои текстът от клавиатурата е необходимо (по-подразбиране) да се натисне клавиша <Enter>. Това може да се промени като се зададе трети аргумент, който е символ и когато функцията срещне този символ тя прекратява въвеждането на текста от клавиаурата. Например
//
get up to 80 chars or until encounter $ sign, place in str
cin.getline(str,
80, '$');
Това извикване на функцията води до прекратяване на входа на текста при натискане на клавиша $ от потребителя. Както може да се очаква декларацията на функцията cin.getline() във файла IOSTREAM.H е нещо подобно на следната значително опростена декларация:
istream getline(char, int, char = '\n'); // simplified declaration
Keywords: С++,
OOP programming , C++ , Classes , Inheritance , Reusability , Creating
New Data Types , Polymorphism and Overloading
Ключови думи: клас
, обект, обектно ориентирано програмиране , полиморфизъм switch if else
?