1. Инлайн функции (Inline Functions). Една инлайн функция се специфицира с ключовата дума inline по следния начин
inline
void func()
{
// statements
}
или ако само се декларира функцията, се пише
inline void func(); // declaration
Извикването на функцията се извършва по обичайния начин:
func();
Обикновено като инлайн функции се дефинират (декларират) къси функции, които се извикват много често в програмата, особено тези извиквани в цикли. На английски това се нарича to inline a function. Ако функцията има голям машинен код, дефинирането и като инлайн функция ще увеличи значително обема на изпълнимия код. На практика много рядко е необходимо потребителят да се грижи за инлайн функциите, защото самият компилатор преценява и прави някои функции такива.
2. Функции на класа, дефинирани в класа (Member Functions Defined Within a Class). Дефиницията на една функция в класа я прави по подразбиране инлайн функция, т.е. те са такива, независимо дали програмистът ги е написал с ключовата дума inline. Да напомним, че функциите дефинирани в класа са функции, чието тяло е в класа, като например следната функция от лекция 16 на класа employee.
void
output() // display employee
data
{
cout << " Name = ";
for (int j = 0; j < n; ++j) // display one character
cout << name[j];
// at a time
cout << "\n Serial number = " << serial_number;
}
Обикновените функции не са инлайн, освен ако програмиста не ги специфицира така с ключовата дума inline.
3. Функции на класа, дефинирани извън класа (Member Functions Defined Outside a Class). Ако искате някоя голяма по код функция на класа да не е инлайн, то трябва да я декларирате в класа и след това да я дефинирате извън класа. Например
class
anyClass //
class specification
{
public:
void anyfunc(); // declaration only
};
// еха до class specification
void
anyClass::anyfunc() // definition outside class
{
// this function is NOT inline
// statements
}
При дефиницията е използван операторът ::, който на английски се нарича Scope Resolution Operator и чийто тромав български превод e оператор за решение за обхвата - вижте дефиницията на обхват - scope. Той е необходим на компилатора, за да разбере функцията на кой клас е, защото тя е написана извън големите скоби на класа.
Както споменахме, така дефинираните функции не са инлайн по подразбиране (by default), но вие въпреки това може да изискате от компилатора да ги направи такива ако използвате ключовата дума inline.
! И в двата случая - на дефиниране на функция в класа и на дефиниране на функция извън класа но с ключовата дума inline при декларацията, което ги прави инлайн функции по подразбиране, компилаторът може да откаже те да бъдат такива. Например, ако има цикли в обявените инлайн функции.
4. Демонстрационна програма. Това е изменена версия на програмата complex3.cpp от лекция 17. в която версия три от функциите на класа compl_num са изнесени извън класа. Обърнете внимание на доста объркващия правопис при дефиницията на третата функция:
complex_number complex_number::root_compl_num(int m, int n)
Повтарянето на два пъти на името на класа се дължи на факта, че функцията връща стойност от типа на класа и че функцията е от този клас (вторият път името на класа е написано преди оператора ::).
//
complex4.cpp
//
a class that models a complex number data type
//
use is made of Member Functions Defined Outside a Class
#include
<iostream.h>
#include
<conio.h>
//for getche()
#include
<math.h>
//for getche()
class
complex_number
{
private:
float real; // real part
float imaginary; // imaginery part
float abs; // absolute value
float arg; // argument
public:
void set()
{
char dummy; // for comma
float a, b;
cout << "Press i for Re + Im*j or press e for Abs*e^Arg: ";
dummy = getche();
if (dummy == 'i')
{
cout << "\nEnter Re: ";
cin >> real;
cout << "Enter Im: ";
cin >> imaginary;
abs = sqrt(real*real + imaginary*imaginary);
if (real != 0)
if (real > 0)
arg = atan(imaginary/real);
else
arg = atan(imaginary/real) + M_PI;
else
if (real > 0)
arg = M_PI/2;
else
arg = -M_PI/2;
}
else
{
cout << "\nEnter Abs: ";
cin >> abs;
cout << "Enter Arg: ";
cin >> arg;
real = abs*cos(arg);
imaginary = abs*sin(arg);
}
} // void set()
void display()
{
cout << '('
<< real // real part
<< " , "
<< imaginary // imaginary part
<< ')';
cout << " ["
<< abs // real part
<< " * e( i*"
<< arg // imaginary part
<< " ) ]";
}
void add(complex_number compl_num);
void mult(complex_number compl_num);
complex_number root_compl_num(int m, int n);
}; // class complex_number
void
complex_number::add(complex_number compl_num)
{
real += compl_num.real;
imaginary += compl_num.imaginary;
}
void
complex_number::mult(complex_number compl_num)
{
complex_number cn;
cn.real = real;
cn.imaginary = imaginary;
real = cn.real*compl_num.real - compl_num.imaginary*cn.imaginary;
imaginary = cn.real*compl_num.imaginary + compl_num.real*cn.imaginary;
}
complex_number
complex_number::root_compl_num(int m, int n)
{
float phase = arg / n;
complex_number root;
root.abs = exp(log(abs)/n);
root.arg = phase + m*2*M_PI/n;
root.real = root.abs*cos(root.arg);
root.imaginary = root.abs*sin(root.arg);
return root;
}
void
main()
{
complex_number c1, c2; // create a
complex_number variable
complex_number c_roots[20]; // create an array of 20 complex_number
variable
int n;
// enter c1
cout << "For c1, ";
c1.set(); // set c1
// show the addition result
cout << "\nc1 = ";
c1.display(); // display c2
// show the addition result
cout << "\nEnter root (n <= 20):";
cin >> n; // display c2
cout << "\n=== The " << n << "th roots are ===\n";
// find n roots of c1
for (int i = 0; i < n; i++)
{
c_roots[i] = c1.root_compl_num(i, n);
}
// display n roots of c1
for (int i = 0; i < n; i++)
{
// show the i-th root
cout << "\nroot[" << i + 1 << "] = ";
c_roots[i].display();
// display c_root[i]
}
// stop the flow on the monitor
getch();
} //end main
Keywords: С++,
OOP programming , C++ , Classes , Inheritance , Reusability , Creating
New Data Types , Polymorphism and Overloading
Ключови думи: клас
, обект, обектно ориентирано програмиране , полиморфизъм switch if else
?