Cpp Chapter 8: Adventures in Functions Part3

8.2.6 Objects, Inheritance, and References

) You might use ostream object cout and ofstream object fout(your declaration), and the object fout could share the methods of ostream class. The language features of passing class features from one to another is called class inheritance. In this example, ostream is termed base class and ofstream is termed derived class. Methods like precision() and setf() in ostream class is also available to ofstream class objects, so you could use same methods will handing console output and file output.

) A base class reference could refer to a derived class object without type cast.

The following example illustrates these features:

 1 // filefunc.cpp -- function with ostream & parameter
 2 #include <iostream>
 3 #include <fstream>
 4 #include <cstdlib>
 5 using namespace std;
 6 
 7 void file_it(ostream & os, double fo, const double fe[], int n);
 8 const int LIMIT = 5;
 9 int main()
10 {
11     ofstream fout;
12     const char * fn = "ep-data.txt";
13     fout.open(fn);
14     if (!fout.is_open())
15     {
16         cout << "Can't open " << fn << ". Bye.\n";
17         exit(EXIT_FAILURE);
18     }
19     double objective;
20     cout << "Enter the focal length of your telescope objective in mm: ";
21     cin >> objective;
22     double eps[LIMIT];
23     cout << "Enter the focal lengths, in mm, of " << LIMIT << " eyepieces:\n";
24     for (int i = 0; i < LIMIT; i++)
25     {
26         cout << "Eyepiece #" << i+1 << ": ";
27         cin >> eps[i];
28     }
29     file_it(fout, objective, eps, LIMIT);
30     file_it(cout, objective, eps, LIMIT);
31     cout << "Done\n";
32     return 0;
33 }
34 
35 void file_it(ostream & os, double fo, const double fe[], int n)
36 {
37     ios_base::fmtflags initial;
38     initial = os.setf(ios_base::fixed); // save initial formatting state
39     os.precision(0);
40     os << "Focal length of objective: " << fo << " mm\n";
41     os.setf(ios::showpoint);
42     os.precision(1);
43     os.width(12);
44     os << "f.l. eyepiece";
45     os.width(15);
46     os << "magnification" << endl;
47     for (int i = 0; i < n; i++)
48     {
49         os.width(12);
50         os << fe[i];
51         os.width(15);
52         os << int(fo / fe[i] + 0.5) << endl;
53     }
54     os.setf(initial);
55 }

29-30) file_it() recieves an ostream-class reference as first parameter, here passes fout and cout consecutively, proving that base-class reference could also accpet derive-class objects without type cast, so these two lines print stuff on console and print it in a file, both using ostream class formatting features.

39/42) precision() specifies the number of digits displayed right to the decimal

43/45/49/51) width() specifies output width range for next output(width(0) means no mandatory stretch or trimming: just display it according to its original quantity)

37/38/54) Code like this is observed:

1 ios_base::fmtflags initial;
2 initial = os.setf(ios_base::fixed);
3 ...
4 os.setf(initial);

The first row declares a variable initial as type ios_base::fmtflags for storing initial pattern. Then initial was assigned to the return value of os.setf(), which returns the original format settings of the ostream object before "setf". After the process, it uses os.setf(initial) to retain the initial formatting by using the stored initial pattern.

8.2.7 When to Use Reference Arguments

There are two main reasons for using reference arguments:

1) To allow you to alter a data object in the calling function

2) To speed up the program by passing a reference instead of an entire data object

Guidelines of choosing between reference, pointer and passing by value:

 No data modifyingmodify data
build-in data typepass by valuepointer
arrayconst pointerpointer
structureconst pointer/referencepointer/reference
class objectconst referencereference

8.3 Default Arguments

) A default argument is a value that's used automatically if you omit the corresponding actual argument from a function call.

) Use function prototype for default arguments.

char * left(const char * str, int n = 1);

In this way you make n a default argument, if you omit value of n, the program will take n for 1.

left(arr, 1);
left(arr);// functions in the same way

) When using a function with an argument list, you must add defaults from left to right:

int f1(int n, int m = 4, int l = 5); // valid
int f2(int n, int m = 3, int l); // invalid
int f3(int n = 1, int m = 2, int l = 3); // valid

For instance, the f1() allows calls with one/two/three parameters. You can't skip arguments like this:

f1(2, , 3); // invalid, doesn't set m to 4

The following exapmle illustrates the features:

 1 // left.cpp -- string function with a default argument
 2 #include <iostream>
 3 const int ArSize = 80;
 4 char * left(const char * str, int n = 1);
 5 int main()
 6 {
 7     using namespace std;
 8     char sample[ArSize];
 9     cout << "Enter a string:\n";
10     cin.get(sample, ArSize);
11     char *ps = left(sample, 4);
12     cout << ps << endl;
13     delete [] ps;
14     ps = left(sample);
15     cout << ps << endl;
16     delete [] ps;
17     return 0;
18 }
19 
20 char * left(const char * str, int n)
21 {
22     if (n < 0)
23         n = 0;
24     char * p = new char[n+1];
25     int i;
26     for (int i = 0; i < n && str[i]; i++)
27         p[i] = str[i];
28     while (i <= n)
29         p[i++] = '\0';
30     return p;
31 }

 

转载于:https://www.cnblogs.com/fsbblogs/p/9703923.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值