2012年1月13日 星期五

Inline Functions


Inline Functions

Functions, either class members or non-class member functions, may be defined as inline. An inline function is one in which the function code replaces the function call directly. Specifying that a function be inline is a request to the compiler that it be inline, but the
compiler may choose not to make it an inline function. This is transparent to the user. Inline functions should be short (preferable one-liners). 

Inline class member functions may be implicit, if they are defined as part of the class definition, or explicit if they are defined outside of the class definition using the keyword, inline.

Inline functions have only internal linkage, that is, they are local to the file in which they are defined.

Example

class xyz
{
  private:
     .
     .
     .
  public:
    void funk1(void) { cout  << "Have a nice day\n"; return; }
    void funk2(void);
     .
     .
};

inline void xyz::funk2(void)
{
  cout << "Ok, don't have a nice day\n";
  return;
}
     .
     .

int main(void)
{
  xyz a,b;
  a.funk1();
  b.funk2();
     .
     .

funk1 is an implicit inline function.  funk2 is an explicit inline function.

Example 3-4 - The Clock class

1      // File: ex3-4.cpp - the Clock class
2     
3      #include <iostream>
4      using namespace std;
5     
6      class Clock
7      {
8        private:
9          int hours;
10          int minutes;
11          int seconds;
12        public:
13          void set(int h, int m, int s)
14            {hours = h; minutes = m; seconds = s; return;}    // inline
15          void increment(void);
16          void display(int=0) const;
17      };
18     
19     
20      void Clock::increment (void)
21      {
22        seconds++;
23        minutes += seconds/60;
24        hours += minutes/60;
25        seconds %= 60;
26        minutes %= 60;
27        hours %= 24;
28        return;
29      }
30     
31     
32      void Clock::display(int format) const
33      {
34        if (format) {             // use format hh:mm:ss AM/PM
35          cout << (hours % 12 ? hours % 12:12) << ':'
36              << (minutes < 10 ? "0" :"") << minutes << ':'
37              << (seconds < 10 ? "0" :"") << seconds
38               << (hours < 12 ? " AM" : " PM") << endl;
39        }
40        else {                   // use format hh:mm:ss (24 hour time)
41          cout << (hours < 10 ? "0" :"") << hours << ':'
42              << (minutes < 10 ? "0" :"") << minutes << ':'
43              << (seconds < 10 ? "0" :"") << seconds << endl;
44        }
45      }
46     
47     
48      int main(void)
49      {
50        Clock c;
51        c.set(23,59,55);
52        for (int i = 0; i < 10; i++) {
53          c.increment();
54          c.display();
55          c.display(1);
56          cout << endl;
57        }
58        return 0;
}


****** Output  ******

23:59:56
11:59:56 PM

23:59:57
11:59:57 PM

23:59:58
11:59:58 PM

23:59:59
11:59:59 PM

00:00:00
12:00:00 AM

00:00:01
12:00:01 AM

00:00:02
12:00:02 AM

00:00:03
12:00:03 AM

00:00:04
12:00:04 AM

00:00:05
12:00:05 AM

Example 3-5 - The Date class

1      // File:  ex3-5.cpp - The Date class
2     
3      #include <iostream>
4      #include <cstring>
5      #include <cstdlib>
6      using namespace std;
7     
8      const unsigned DaysPerMonth[] =
9         {31,28,31,30,31,30,31,31,30,31,30,31};
10     
11      class Date
12      {
13          unsigned day;
14          unsigned month;
15          unsigned year;
16          void errmsg(const char* msg);
17      public:
18          void set(const char* mmddyy);
19          void increment(void);
20          void display(void) const;
21      };
22     
23      void Date::set(const char* mm_dd_yy)
24      {
25          char* temp;
26          char copy[9];
27     
28          // assume user enters date as mm/dd/yy
29          if (strlen(mm_dd_yy) != 8) errmsg(mm_dd_yy);
30     
31          // use a copy of mm_dd_yy    What is the impact to the function?
32          strcpy(copy,mm_dd_yy);
33     
34          // parse the date and get the month
35          temp = strtok(copy,"/");    // strtok() replaces "/" with a NULL
36          if (temp != NULL) month = atoi(temp);
37          else errmsg(copy);
38     
39          // parse the date and get the day
40          temp = strtok(NULL,"/");    // strtok() finds the next "/"
41          if (temp != NULL) day = atoi(temp);
42          else errmsg(copy);
43     
44          // parse the date and get the year
45          temp = strtok(NULL,"/");
46          if (temp != NULL) year = atoi(temp);
47          else errmsg(copy);
48     
49          // Make a Y2K correction for a 2-digit year
50          if (year < 50) year += 2000;
51          else if (year < 100) year += 1900;
52          else ;    // assume the year is right
53      }
54     
55      void Date::increment (void)
56      {
57          // increment the day
58          day++;
59     
60          // check for the end of the month
61          if (day > DaysPerMonth[month - 1])  // past end of current month?
62          {
63              month ++;
64              day = 1;
65          }
66     
67          // check for the end of the year
68          if (month > 12)
69          {
70              year ++;
71              month = 1;
72          }
73     
74          return;
75      }
76     
77      void Date::display(void) const
78      {
79          cout << "The date is " << month << '/' << day << '/'
80              << (year%100< 10?"0":"") << year%100 << endl;
81          if (day % DaysPerMonth[month-1] == 0) cout << endl;
82          return;
83      }
84     
85      void Date::errmsg(const char* msg)
86      {
87          cerr << "Invalid date format: " << msg << endl;
88          exit(EXIT_FAILURE);
89      }
90     
91      int main(void)
92      {
93          Date d;
94          char mmddyy[9];
95          cout << "Enter the starting date <mm/dd/yy> => ";
96          cin >> mmddyy;
97          d.set(mmddyy);
98          for (int i = 0; i < 375; i++)
99          {
100              d.display();
101              d.increment();
102          }
103          return 0;
104      }


******  Sample Output #1  ******

Enter the starting date <mm/dd/yy> => 4/20/09
Invalid date format: 1/20/09


******  Sample Output #2  ******

Enter the starting date <mm/dd/yy> => 04/20/09
The date is 4/20/09
The date is 4/21/09
The date is 4/22/09
The date is 4/23/09
The date is 4/24/09
The date is 4/25/09
The date is 4/26/09
The date is 4/27/09
The date is 4/28/09
The date is 4/29/09
The date is 4/30/09

The date is 5/1/09
The date is 5/2/09
The date is 5/3/09
The date is 5/4/09
The date is 5/5/09
The date is 5/6/09
The date is 5/7/09
The date is 5/8/09
The date is 5/9/09
The date is 5/10/09

The date is 12/29/09
The date is 12/30/09
The date is 12/31/09

The date is 1/1/10
The date is 1/2/10
The date is 1/3/10
The date is 1/4/10
The date is 1/5/10
The date is 1/6/10

The date is 4/24/10
The date is 4/25/10
The date is 4/26/10
The date is 4/27/10
The date is 4/28/10
The date is 4/29/10

What is the effect of making errmsg() private in the class?

How does strtok() work?

Is there a difference if line 40 is coded like this? temp = strtok(NULL,"/");
No, not really, in C++ the macro NULL is defined as (integer) 0.

How would you make this program work for leap years?

How would you change display() to print the date with a two-digit month and day?

What is atoi() and how does it work?  Why is it not considered "safe"?

Practice problem:  Modify this program to print the date as "m/dd/yy" and to handle leap years?

Example 3-6 - The quadratic (Equation) class

1      // File:  ex3-6.cpp - the quadratic class
2     
3      #include <iostream>
4      #include <cmath>
5      using namespace std;
6     
7      class quadratic
8      {
9      private:
10          float a, b, c;
11      public:
12          void set(float f1, float f2, float f3)
13               {a = f1; b = f2; c = f3; return;}
14          void solve(void) const;
15          void display(void) const;
16      };
17     
18      void quadratic::solve (void) const
19      {
20          bool complex_roots;
21          float radical_stuff;
22          if (a == 0)
23          {
24              cout <<
25               "This is not a quadratic equation.  It has only one root "
26                  << -c/b << endl;
27              return;
28          }
29          complex_roots = (radical_stuff = b * b - 4 * a * c) < 0;
30          cout << "The roots of the equation are ";
31          if (!complex_roots)
32              cout << ((-b+sqrt(radical_stuff))/(2.*a))
33              <<" and " << ((-b-sqrt(radical_stuff))/(2.*a)) << endl;
34          else
35              cout << (-b/(2.*a)) <<'+'<< sqrt(-radical_stuff)/(2.*a)<<'i'
36              <<
37              " and "
38              << (-b/(2.*a)) << '-' << sqrt(-radical_stuff)/(2.*a) << 'i'
39              <<endl;
40          return;
41      }
42     
43      void quadratic::display(void) const
44      {
45          cout << "The coefficients of the quadratic equations are: "
46              << a << ", " << b << ", and " << c <<endl;
47          return;
48      }
49     
50      int main(void)
51      {
52          quadratic equation;
53          float a,b,c;
54          while (1)
55          {
56              cout <<
57             “Enter 3 coeffients for a quadratic equation (or quit) => ";
58              if (!(cin >> a >> b >> c)) break;
59              equation.set(a,b,c);
60              equation.display();
61              equation.solve();
62              cout << endl;
63          }
64          return 0;
65      }


******  Sample Run  ******

Enter 3 coefficients for an equation (or quit) => 1 2 1
The coefficients of the quadratic equations are: 1, 2, and 1
The roots of the equation are -1 and -1

Enter 3 coefficients for an equation (or quit) => 1 0 -1
The coefficients of the quadratic equations are: 1, 0, and -1
The roots of the equation are 1 and -1

Enter 3 coefficients for an equation (or quit) => 1 2 3
The coefficients of the quadratic equations are: 1, 2, and 3
The roots of the equation are -1+1.414214i and -1-1.414214i

Enter 3 coefficients for an equation (or quit) => 1 1 1
The coefficients of the quadratic equations are: 1, 1, and 1
The roots of the equation are -0.5+0.866025i and -0.5-0.866025i

Enter 3 coefficients for an equation (or quit) => 0 3 6
The coefficients of the quadratic equations are: 0, 3, and 6
This is not a quadratic equation. It has only one root -2

Enter 3 coefficients for an equation (or quit) => quit

How does the line: if (!(cin >> a >> b >> c)) break;   work?

Example 3-7 - The card and deck classes

This example demonstrates a container relationship between classes.  This is also called containment.

1      // File: ex3-7.cpp - card and deck classes
2     
3      #include <iostream>
4      #include <cstdlib>                 // needed for rand() function
5      using namespace std;
6     
7      const char* value_name[13] = {"two","three","four","five","six",
8        "seven","eight","nine","ten","jack","queen","king","ace"};
9     
10      const char* suit_name[4] = {"clubs","diamonds","hearts","spades"};
11     
12      class card
13      {
14        private:
15            int value;
16            int suit; 
17        public:
18            void assign(int);
19            int get_value(void) const;             // accessor function
20            int get_suit(void) const;                // accessor function
21            void print(void) const;
22      };
23     
24      void card::assign(int x)
25      {
26        value = x % 13;
27        suit = x / 13;
28        return;
29      }
30     
31      int card::get_value(void) const
32      {
33        return value;
34      }
35     
36      int card::get_suit(void) const
37      {
38        return suit;
39      }
40     
41      void card::print(void) const
42      {
43        cout << (value_name[value]) << " of "
44            << (suit_name[suit]) << endl;
45        return;
46      }
47      class deck
48      {
49        private:
50            card d[52];
51            int next_card;
52        public:
53            void create_deck(void);
54            void shuffle(void);
55            void deal(int=5);
56            void print(void) const;
57      };
58     
59     
60      void deck::create_deck(void)
61      {
62        for (int i = 0; i < 52; i++) d[i].assign(i);
63        next_card = 0;
64        return;
65      }
66     
67     
68      void deck::shuffle(void)
69      {
70        int i, k;
71        cout << "I am shuffling the deck\n";
72        for (i = 0; i < 52; i++)
73        {
74            k = rand() % 52;
75            card temp = d[i];
76            d[i] = d[k];
77            d[k] = temp;
78        }
79        return;
80      }
81     
82     
83      void deck::print(void) const
84      {
85        cout << "\nHere's the deck:\n";
86        for (int i = 0; i < 52; i++) d[i].print();
87        return;
88      }
89     
90      void deck::deal(int no_of_cards)
91      {
92        cout <<"\nOk, I will deal you "<<no_of_cards<<" cards:\n";
93        for (int i=0; i<no_of_cards; i++) d[next_card++].print();
94        return;
95      }
96      int main(void) {
97        deck poker;
98        poker.create_deck();
99        poker.print();
100        poker.shuffle();
101        poker.print();
102        poker.deal();
103        poker.deal(3);
104        return 0;
105      }


******  Output  ******

Here's the deck:
two of clubs
three of clubs
four of clubs
five of clubs
six of clubs
seven of clubs
eight of clubs
nine of clubs
     .    .
     .    .
ace of spades
I am shuffling the deck

Here's the deck:
ten of hearts
ace of diamonds
queen of clubs
three of diamonds
four of spades
eight of spades
eight of diamonds
     .    .
     .    .
Ok, I will deal you 5 cards:
ten of hearts
ace of diamonds
queen of clubs
three of diamonds
four of spades

Ok, I will deal you 3 cards:
eight of spades
eight of diamonds
eight of clubs

Inline function 為 function code 取代 function call.

沒有留言:

張貼留言