临沂网站制作报价,国内知名的app开发,wordpress炫酷背景图片,wordpress评论链接转换第十七章 特殊类成员 1.1 静态成员变量 假如我们要在一个类中的所有对象间共享某种数据#xff0c;那不妨将其设置为静态成员变量/函数#xff1b; static x 1.2 静态成员变量 静态成员变量与成员变量有4点不同#xff1a; ①前者属于类②前者必须在全局定义③前者被调用…第十七章 特殊类成员 1.1 静态成员变量 假如我们要在一个类中的所有对象间共享某种数据那不妨将其设置为静态成员变量/函数 static x 1.2 静态成员变量 静态成员变量与成员变量有4点不同 ①前者属于类②前者必须在全局定义③前者被调用只用说明那个类即可④前者在没有创建对象之前就已经存在 1 #include iostream2 using namespace std;3 class A 4 {5 public:6 static int n;7 };8 int A::n0; //要使用类成员限定来访问静态成员9 void show(){coutA::na \n;}
10 int main()
11 {
12 int i;
13 for(i0;i5;i)
14 {
15 A::n; //访问静态成员变量n并对其进行自加操作............公有的可以直接访问①
16 show(); //调用全局函数show该函数输出静态成员变量n的值
17 }
18 return 0;
19 } 2. 私有静态成员变量 1 #include iostream2 using namespace std;3 class A 4 {5 public:6 void func(){coutA::xendl;;} //定义公有成员函数func()用该函数访问私有静态成员变量x7 private:8 static int x; //将静态成员变量x声明为私有9 };
10 int A::x1000; //定义并初始化静态成员变量
11 int main()
12 {
13 A a; //创建一个对象
14 a.func(); //用该对象访问公有成员函数func()
15 //cout A::x endl; //注意不能直接访问...............私有的不可以直接访问①
16 return 0;
17 } 3. 静态成员函数 静态成员函数在未创建对象时也可以使用它的使用和静态成员变量一样 ① 1 /*2 #include iostream3 using namespace std;4 class A5 {6 public:7 void static show(){coutA::n;n;} //注意静态成员函数不能访问某个对象的成员变量因为他没有指向该对象的this指针。不过它可以访问该类的静态成员变量 ②8 private:9 static int n; //声明私有静态成员变量n
10 };
11 int A::n0; //定义私有静态成员变量n
12 int main()
13 {
14 int i;
15 for(i0;i5;i)
16 {
17 A::show(); //循环调用公有静态成员函数show()
18 coutendl;
19 }
20 return 0;
21 }
22 */
23
24 /*
25 //另外我们也可以通过对象来访问静态成员函数如
26 #include iostream
27 using namespace std;
28 class A
29 {
30 public:
31 void static show(){coutA::n;n;}
32 private:
33 static int n;
34 };
35 int A::n0;
36 int main()
37 {
38 A a,b,c;
39 a.show();
40 b.show();
41 c.show();
42 return 0;
43 }
44 */
45
46
47
48 #include iostream
49 using namespace std;
50 class A
51 {
52 public:
53 void show(int i){xi;coutx;}
54 //void static show1(int j){xj;coutx;}
55 //静态成员函数没有指向对象的this指针所以不能访问对象的成员数据
56 private:
57 int x;
58 };
59 int main()
60 {
61 A a;
62 a.show(1);
63 //a.show1(2);
64 //不能通过静态成员函数访问自己的成员变量
65 return 0;
66 } 4. 静态成员的使用 静态成员可以被继承。 类中任何成员函数都可以访问静态成员但是静态成员函数不能直接访问非静态成员静态成员函数不能说明为虚函数 1 #include iostream2 using namespace std;3 class aspl //将阿司匹林声明为一个aspl类那么每箱阿司匹林就是该类的一个对象 4 {5 public:6 aspl(float p){pricep;TotalPricepTotalPrice;} //在构造函数中实例化该对象的私有成员变量price这样就得到了一箱阿司匹林并且有了它的初始价格7 ~aspl(){TotalPriceTotalPrice-price;} //析构函数销毁该对象并且将总价格减去该箱的价格这样账面上就少了一箱阿司匹林并且总价格也减去了该箱的价格8 static float get(){return TotalPrice;}9 private:
10 float price; //由于每箱阿司匹林都有价格因此必须得有个成员变量来表示价格这里在aspl这个类中声明一个私有成员变量price
11 static float TotalPrice; //由于阿司匹林的总价格属于类的总价格而不是某一箱阿司匹林的价格因此我们要将总价格声明为静态成员变量这里声明为TotalPrice
12 };
13 float aspl::TotalPrice0; //静态成员变量必须初始化
14 void main()
15 {
16 float f;
17 cout阿司匹林的库存总价格为;
18 coutaspl::get()endl; //必须用类名限定符来调用静态成员函数
19 int i0;
20 cout请输入第i1次购进的阿司匹林的单箱价格;
21 cinf;
22 aspl *p[5]; //定义了5个指向aspl类的数组指针p
23 p[i]new aspl(f); //购进一箱阿司匹林
24 cout阿司匹林的库存总价格为;
25 coutaspl::get()endl; //输出总价格
26 i; //i代表购进的次数i表示将要进行i1次购进
27 cout请输入第i1次购进的阿司匹林的单箱价格; //提示用户输入i次购进
28 cinf;
29 p[i]new aspl(f); //输入的数值保存在i次购进的对象的成员变量中
30 cout阿司匹林的库存总价格为;
31 coutaspl::get()endl; //输出当前的库存总价格
32 cout请输入卖出的阿司匹林的编号,编号即第几次购进;//提示用户要删除哪次购进
33 cini; //将输入值保存在i变量中
34 delete p[i]; //删除第i次创建的对象
35 cout阿司匹林的库存总价格为;
36 coutaspl::get()endl; //再次输出销售一箱阿司匹林后的库存总价格
37 } 5. 函数指针 long(*func1)(int); //声明了一个函数指针 long* func2(int); //声明了一个返回指针的函数 第一种定义了一个叫func1的函数指针该指针指向一个含有int型参数并且返回值为long型的函数 函数指针名可以看作函数名的代号我们可以通过它来直接调用函数所以函数指针经常会在条件或者判断语句里出现以便于用户选择调用不同名字但又类型和参数相同的函数。 另外要注意的是函数指针可以指向某个函数但是前提是被指向的函数的参数和返回至都与该函数指针被声明时的返回值和参数相吻合 1 #include iostream2 #include string3 using namespace std;4 bool check(string str) //检测是否是数字的函数要注意该函数一定要放在调用函数的上面5 {6 for(int i 0;istr.length();i)7 if((str[i]9 || str[i]0)(str[i]!.))8 return false;9 return true;
10 }
11 float triangle(float x,float y)
12 {
13 return x*y*0.5;
14 }
15 float rectangle(float x,float y)
16 {
17 return x*y;
18 }
19 void Swap(float x,float y)
20 {
21 float n;
22 nx;
23 xy;
24 yn;
25 }
26 void print(float x,float y)
27 {
28 cout长为:x 宽为:yendl;
29 }
30 void get(float a ,float b)
31 {
32 cout请输入x的新值:;
33 string str1;cinstr1;
34 while(!check(str1)) //调用检测数字函数如果返回值为假执行该循环为真退出
35 {
36 cout输入的不是数字,请重新输入!!!endl;
37 cinstr1;
38 }
39 a atof(str1.c_str()); //将字符串转换为浮点数
40 cout请输入y的新值:;
41 string str2;cinstr2;
42 while(!check(str2)){
43 cout输入的不是数字,请重新输入!!!endl;
44 cinstr2;
45 }
46 b atof(str2.c_str());
47 }
48 int main()
49 {
50 void(*p)(float ,float ); //声明一个函数指针p该指针指向一个返回void值并且带有两个float参数的函数
51 float(*fp)(float , float ); //声明一个函数指针fp该指针指向一个返回float值并且带有两个float参数的函数
52 bool quitfalse;
53 float a2,b3; //定义两个参数a和b的值
54 int choice; //声明选择参数choice
55 while(quitfalse)
56 {
57 cout(0)退出(1)设定长宽(2)三角形(3)矩形(4交换长宽;
58 cinchoice;
59 switch(choice) //条件判断语句
60 {
61 case 1:
62 pget; //用指针p来指向函数名get该函数带有两个float参数并返回一个void值与函数指针p的参数和类型相吻合
63 break;
64 case 2:
65 fptriangle; //用指针fp来指向函数名triangle该函数带有两个float参数并返回一个float值与函数指针fp的参数和类型相吻合
66 break;
67 case 3:
68 fprectangle; //用指针fp来指向函数名rectangle该函数带有两个float参数并返回一个float值与函数指针fp的参数和类型相吻合
69 break;
70 case 4:
71 pSwap; //用指针p来指向函数名swap该函数带有两个float参数并返回一个void值与函数指针p的参数和类型相吻合
72 break;
73 default:
74 quittrue;
75 break;
76 }
77 if(quit)break;
78 if(choice1||choice4) //假如选择了第1或者第4项
79 {
80 print(a,b);
81 p(a,b); //调用函数指针p所指向的函数该指针指向的是一个返回值为void的函数由于不同的选项中将不同的函数名赋给了指针p因此选择不同则调用的函数也不同
82 print(a,b);
83 }
84 else if(choice2||choice3) //假如选择了第2和第3项
85 {
86 print(a,b);
87 cout面积为fp(a,b)endl; //调用函数指针fp所指向的函数该指针指向的是一个返回值为float的函数由于不同的选项中将不同的函数名赋给了指针fp因此选择不同则调用的函数也不同
88 }
89 }
90 return 0;
91 } 6. 函数指针数组 void(*p[5])(float ,float ); 7. 函数指针也可以作为函数的参数 1 #include iostream2 using namespace std;3 void square(int x,int y)4 {5 xx*x;6 yy*y;7 }8 void cube(int x,int y)9 {
10 xx*x*x;
11 yy*y*y;
12 }
13 void Swap(int x,int y)
14 {
15 int z;
16 zx;
17 xy;
18 yz;
19 }
20 void print(void(*p)(int x,int y),int x,int y) //该函数有3个参数第1个是一个函数指针p它指向的函数带有两个参数
21 //并返回一个void值另外还有两个int型引用x和y
22 {
23 cout执行函数前\n;
24 coutxx\tyyendl;
25 p(x,y);
26 cout执行函数后\n;
27 coutxx\tyyendl;
28 }
29 int main()
30 {
31 int a2,b3;
32 char choice;
33 bool quitfalse;
34 void (*p)(int ,int );
35 //声明的p为一个函数指针它所指向的函数带有两个参数并返回 一个void值
36 while(quitfalse)
37 {
38 cout(0)退出(1)平方(2)立方(3)交换参数;
39 cinchoice;
40 switch(choice)
41 {
42 case 0:quittrue;
43 case 1:psquare;break; //输入1将函数名square的地址赋给p
44 case 2:pcube;break; //输入2将函数名cube的地址赋给p
45 case 3:pSwap;break; //输入3将函数名Swap的地址赋给p
46 default:p0;break;
47 }
48 if(quittrue)break;
49 if(p0)
50 {
51 cout请输入0到3之间的数字\n;
52 continue;
53 }
54 print(p,a,b); //调用将函数指针作为参数的函数print
55 }
56 return 0;
57 } 8. 使用typedef简化函数指针的声明 1 //typedef 可以简化代码 可以为现有类型创建一个新的名字或者声明一个对象为某个新类型typedef void(*vp)(int ,int );2 //#define f(x) x*x ≠ #define f(x) (x*x) typedef要比#define要好特别是在有指针的场合 再比如3 // typedef char* pStr1; //后面代替前面4 // #define pStr2 char* //没有分号前面代替后面5 // pStr1 s1, s2; //定义了两个char* 6 // pStr2 s3, s4; //定义了一个char* s3 一个char s47 //8 9 #include iostream
10 using namespace std;
11 typedef void(*vp)(int ,int );//typedef 将vp声明为一个函数指针类型该类型的指针指向一个带有两个int型引用参数并返回void的函数
12 void square(int x,int y)
13 {
14 xx*x;
15 yy*y;
16 }
17 void cube(int x,int y)
18 {
19 xx*x*x;
20 yy*y*y;
21 }
22 void Swap(int x,int y)
23 {
24 int z;
25 zx;
26 xy;
27 yz;
28 }
29 void print(vp,int ,int ); //print函数的声明部分该函数有三个参数一个vp类型的函数指针两个int型引用。
30 int main()
31 {
32 vp p;
33 int a2,b3;
34 char choice;
35 bool quitfalse;
36 while(quitfalse)
37 {
38 cout(0)退出(1)平方(2)立方(3)交换参数;
39 cinchoice;
40 switch(choice)
41 {
42 case 0:quittrue;
43 case 1:psquare;break; //输入将函数名square的地址赋给p
44 case 2:pcube;break; //输入将函数名cube的地址赋给p
45 case 3:pSwap;break; //输入将函数名Swap的地址赋给p
46 default:p0;break;
47 }
48 if(quittrue)break;
49 if(p0)
50 {
51 cout请输入0到3之间的数字\n;
52 continue;
53 }
54 print(p,a,b); //调用这个将函数指针作为参数的函数
55 }
56 return 0;
57 }
58 void print(vp p,int x,int y) //print函数的定义部分函数头声明了3个接收参数第1个是vp类型的函数指针p它指向的函数带有两个参数并返回一个void值另外还有两个int型引用x和y
59 {
60 cout执行函数前\n;
61 coutxx\tyyendl;
62 p(x,y);
63 cout执行函数后\n;
64 coutxx\tyyendl;
65 } 9. 类的函数指针 1 #include iostream2 using namespace std;3 class human //抽象类human4 {5 public:6 virtual void run()0; //纯虚函数run7 virtual void eat()0; //纯虚函数eat8 };9 class mother:public human //派生类mother从抽象类human继承
10 {
11 public:
12 void run(){cout母亲跑百米要花二十秒\n;} //覆盖纯虚函数run
13 void eat(){cout母亲喜欢吃零食\n;} //覆盖纯虚函数eat
14 };
15 class father: public human //派生类father从抽象类human继承
16 {
17 public:
18 void run(){cout父亲跑百米要花十秒\n;} //覆盖纯虚函数run
19 void eat(){cout父亲不喜欢吃零食\n;} //覆盖纯虚函数eat
20 };
21 class uncle:public human //派生类uncle从抽象类human继承
22 {
23 public:
24 void run(){cout舅舅跑百米要花十一秒\n;} //覆盖纯虚函数run
25 void eat(){cout舅舅喜欢偷吃零食\n;} //覆盖纯虚函数eat
26 };
27 int main()
28 {
29 void(human::*pf)()0; //声明一个成员函数指针pf该指针属于抽象类human
30 human* p0; //声明一个指向抽象类human的指针p并将它的内存地址赋为0
31 char choice1,choice2; //声明两个字符变量用来保存两次用户输入的字符
32 bool quitfalse; //声明一个布尔变量quit作为while循环的条件
33 while(quitfalse) //当quit为真时退出循环
34 {
35 cout(0)退出(1)母亲(2)父亲(3)舅舅:; //选择菜单
36 cinchoice1; //将用户的第1次选择保存在choice1中
37 switch(choice1) //将该选择作为判断的依据
38 {
39 case 0:quittrue;break; //假如输入了字符0那么将quit的值赋为真然后退出switch循环
40 case 1:pnew mother;break; //假如输入了字符1那么创建mother类的新对象并将p指向它,然后退出switch循环
41 case 2:pnew father;break; //假如输入了字符2那么创建father类的新对象并将p指向它,然后退出switch循环
42 case 3:pnew uncle;break; //假如输入了字符3那么创建uncle类的新对象并将p指向它,然后退出switch循环
43 default:choice1q;break; //将字符q赋给choice1,然后退出switch循环
44 }
45 if(quit) //假如quit的值为真
46 break; //退出while循环
47 if(choice1q) //假如choice1的值为字符q
48 { cout请输入0到3之间的数字\n;
49 continue;
50 } //输出警告并跳转到while循环的开始处继续执行
51 cout(1)跑步(2)进食\n; //输出选择菜单
52 cinchoice2; //将第2次用户的选择保存在choice2中
53 switch(choice2) //将用户的第2次选择作为判断的依据
54 {
55 case 1:pfhuman::run;break; //假如输入了字符1那么将基类human的虚函数run的内存地址赋给成员函数指针然后退出switch循环。注意这里的号是取human类成员函数run的地址
56 case 2:pfhuman::eat;break; //假如输入了字符2那么将基类human的虚函数eat的内存地址赋给成员函数指针然后退出switch循环
57 default:break; //退出switch循环
58 }
59 (p-*pf)(); //通过指针p来访问对象通过*pf来访问该对象的成员函数
60 delete p; //删除p指针因为*pf指向的不是对象而是该对象的成员函数所以没有必要删除pf
61 }
62 return 0;
63 } 10. 成员函数指针数组 1 #include iostream2 using namespace std;3 class paper4 {5 public:6 void read(){cout纸上面的字可以读\n;}7 void write(){cout纸可以用来写字\n;}8 void burn(){cout纸可以用来点火\n;}9 };
10 typedef void(paper::*p)(); //利用typedef声明一个成员函数指针类型p该类型的指针指向paper类的成员函数该函数不具返回值且没有参数
11 int main()
12 {
13 //成员函数指针指向三个成员函数
14 p func[3]{paper::read,paper::write,paper::burn};//用类型p来声明一个func成员函数指针数组并将它的成员函数指针初始化为它们所指向的函数的内存地址。
15 //与普通数组元素一样成员函数指针数组的每个成员函数指针也会拥有一个编号该编号从0开始
16 paper* pp0; //声明一个指向paper类的普通指针
17 char choice[1]; //声明一个只保存一个字符的char型数组choice
18 bool quitfalse; //声明一个布尔变量quit并将它的值赋为false
19 while(quitfalse) //当quit的值为false时
20 {
21 cout(0)退出(1)读(2)写(3)点火; //输出选择菜单
22 cinchoice[0]; //将用户的选择保存在字符数组choice中
23 if(choice[0]3 || choice[0]0) //判断该字符是否在0到3之间假如不是
24 {
25 cout请输入从0~3之间的数字\n; //提示用户输入
26 }
27 //否则假如输入的字符在0~3之间
28 else if (choice[0]0) //再判断该字符是否等于0
29 {
30 quittrue; //等于的话将quit赋为true那么while条件不成立退出循环
31 }
32 else
33 {
34 int n; //定义一个整型变量用来接收被转换为整型的字符串
35 ppnew paper; //新构造一个paper类对象用pp来指向它
36 natoi(choice); //将choice转换为整型后再赋给n
37 (pp-*func[n-1])(); // pp指针访问新对象的成员函数由该对象调用func 指针数组中下标为n-1的指针指向的成员函数这里要注意数组的下标n是用户输入的选项值由于数组元素从0开始所以要n减1,后面的()表示函数无参数
38 delete pp; //删除pp指针指向的新对象
39 }
40 }
41 return 0;
42 } 转载于:https://www.cnblogs.com/zenseven/p/3799044.html