mutable
You haven't heard the entire truth about const member functions. The definition stated earlier was, "A const member function is a class member function that may not make any changes to any of the data members of the class". Actually, there is an exception to this. The keyword, mutable, allows the user to supersede the const intension. A class member that is defined using the storage specifier, mutable, may be changed in a const member function. Here is example 3-8 again with a mutable class member:
1 // File: ex3-8m.cpp - const member function with a mutable member
2
3 void makeit6(int& I)
4 {
5 I = 6;
6 }
7
8
9 class ABC
10 {
11 mutable int x;
12 public:
13 void funk();
14 void gunk() const; // const member function
15 void hunk(int&);
16 void junk(int&) const; // const member function
17 void lunk(const int&);
18 void munk(const int&) const; // const member function
19 };
20
21 void ABC::funk()
22 {
23 x = 6; // ok
24 makeit6(x); // ok
25 makeit6(6); // error: cannot convert const int to int&
26 }
27
28 void ABC::gunk() const
29 {
30 x = 6; // ok
31 makeit6(x); // ok
32 }
33
34 void ABC::hunk(int &I)
35 {
36 x = 6; // ok
37 makeit6(I); // ok
38 makeit6(x); // ok
39 }
40
41 void ABC::junk(int &I) const
42 {
43 x = I; // ok
44 makeit6(I); // ok
45 makeit6(x); // ok
46 }
47
48
49 void ABC::lunk(const int &I)
50 {
51 x = I; // ok
52 makeit6(I); // error: cannot pass const int& as int&
53 makeit6(x); // ok
54 }
55
56 void ABC::munk(const int &I) const
57 {
58 x = I; // ok
59 makeit6(I); // error: cannot pass const int& as int&
60 makeit6(x); // ok
61 }
62
63
64 int main()
65 {
66 ABC object;
67 int i = 3;
68 object.funk();
69 object.gunk();
70 object.hunk(i);
71 object.junk(i);
72 object.lunk(i);
73 object.munk(i);
74
75 return 0;
76 }No output – compile errors
mutable should be used in a situation where you want a member function to only be able to change a few of the class members, not all of them.
Classes Containing Enumerated Types
Example 3-9 - Enums and classes
1 // File: ex3-9.cpp - enums and classes
2
3 #include <iostream>
4 using namespace std;
5
6 enum size {small, medium, large};
7
8 class thing
9 {
10 public:
11 enum color {red, white, blue};
12 enum {FALSE, TRUE }; // anonymous enum
13 void setBigness(size=small);
14 void setHue(color=red);
15 size getBigness() const;
16 color getHue() const;
17 int amIBlue() const
18 { if (hue == blue) return TRUE; else return FALSE; }
19 private:
20 size bigness;
21 color hue;
22 };
23
24 void thing::setBigness(size s)
25 {
26 bigness = s;
27 }
28
29 void thing::setHue(color c)
30 {
31 hue = c;
32 }
33
34 size thing::getBigness() const
35 {
36 return bigness;
37 }
38
39 thing::color thing::getHue() const // note difference to prototype
40 { // this is required
41 return hue;
42 }
43
44
45 thing::color nonMember(const thing&); // function prototype
46 int main() {
47 size S = large;
48 thing::color C = thing::white;
49
50 thing Big_red_thing;
51 Big_red_thing.setBigness(S);
52 Big_red_thing.setBigness(medium);
53 Big_red_thing.setHue();
54 cout << "I am"
55 << (Big_red_thing.amIBblue() ? " " : " not ")
56 << "blue\n";
57
58 thing Little_blue_thing;
59 Little_blue_thing.setBigness();
60 // Little_blue_thing.setHue(blue);
61 Little_blue_thing.setHue(thing::blue);
62 cout << "I am"
63 << (Little_blue_thing.amIBlue() ? " " : " not ")
64 << "blue\n";
65 Little_blue_thing.setHue(C);
66 cout << "I am"
67 << (Little_blue_thing.amIBlue() ? " " : " not ")
68 << "blue\n";
69
70 nonMember(Big_red_thing);
71
72 return 0;
73 }
74
75 thing::color nonMember(const thing& T) {
76 return T.getHue();
77 }****** Output ******
I am not blue
I am blue
I am not blue
Note: An enumerated type defined within a class is subject to access specifiers, just like data members or member functions. In other words, if the color type in the thing class of this example is specified as private, then that type is not visible except to class member functions.
當你想要 member function 可以改變部分的 class members, 可以使用 mutable.
enumerated type 的 access specifiers 與 data members 與 member functions 相同.
沒有留言:
張貼留言