Програмен език C++
Част 26

Аргументи по подразбиране

(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

.
(съдържание)
.
Литература
.
[1] Robert Lafore; C++ Interactive Course. Waite Group Press, Macmillan Computer Publishing, 1996.
.
Автор: Проф. Процесор Аритметиков
.
[ това е материал от брой 26 от декември 2008 г - януари 2009 г на списание "Коснос" www.kosnos.com ]

Keywords: С++,  OOP programming , C++ , Classes , Inheritance , Reusability , Creating New Data Types , Polymorphism and Overloading
Ключови думи: клас , обект, обектно ориентирано програмиране , полиморфизъм switch if else ?