菜鸟的C++学习(三)

1.静态成员:静态数据成员在类外定义,在类内声名;

//静态数据成员

#include <iostream.h>

class Student{

public:   

       static int count;      //声名为静态数据成员

       int StudentNo;

public:

       Student()

       {     count++; //创建一个Student count 加加

              StudentNo=count;

       }

       void print()

       {     cout<<"Student "<<StudentNo<<" ";

              cout<<"count="<<count<<endl;

       }

};

 

int Student::count=0;     //定义静态数据成员并初始化

 

void main()

{    

       Student s1;

       s1.print();

       cout<<"------/n";

 

       Student s2;

       s1.print();

       s2.print();

       cout<<"------/n";

       //可以在外面操作变量

       //Student::count=99  此时输出:1-22-100 100 100

       Student s3;

       s1.print();

       s2.print();

       s3.print();

       cout<<"------/n";

}

结果:1-22-333

2.所以当使用全局变量的时候,可以使用静态成员,函数间是共享的。其实啊类是不能分配空间的,因为是个声明而已,初始化才赋值。

3.使用静态使得可以代替全局,这样就符合C++封装性!一般用来定义一些共有的数据;如统计总数、平均数等。

// 使用静态成员函数访问静态数据成员

#include <iostream.h>

class small_cat{

private:

       double weight;

       static double total_weight;     //静态数据成员

       static double total_number;    //静态数据成员

public:

       small_cat(double w)

       {     weight=w;

              total_weight+=w;

              total_number++;

       }

       void display()

       {

              cout<<"小猫的重量是:"<<weight<<""<<endl;

       }

       //static void total_disp() //静态成员函数

       void total_disp()

       {

              cout<<total_number<<"只小猫总重是:"<<total_weight<<""<<endl;

       }

};

double small_cat::total_weight=0;

double small_cat::total_number=0;

void main()

{     small_cat w1(1.88),w2(1.66),w3(1.55);

       w1.display();

       w2.display();

       w3.display();

       small_cat::total_disp();   //通过类调用静态成员函数

//     w1.total_disp();

}

4.对静态成员的访问采用的是 类名::对象.静态成员函数名()也对;

在声明时加static(类的里面用),使用时只需 类名::静态成员函数名()

5.一般而言,静态成员函数不能访问类中的非静态成员。(因为没有this指针,不知道该访问哪个对象的成员了)

6. // 使用友元函数

#include <iostream.h>

#include <string.h>

class girl{

private:

       char *name;

       int age;

public:

       girl(char *n,int d)

       {     name=new char[strlen(n)+1];

              strcpy(name,n);

              age=d; //实际 this->age = d;隐藏了this指针。

       }

 

       friend void disp(girl &);       //声明为友元函数,可以放在共有或私有的部分。不能值传递!

// friend void disp(girl x); 错误!涉及内存权限。虽然可以通过编译,指针可以

 

新建的对象xe的所有均复制到x

name  age

对象e

name

age

同一块内存释放两次 (值传递时把name 的地址复制给新开的 name 中,x name 又指向原始的name

 

 

new

new

 

 


       ~girl(){delete name;}

};

 

 

但是传值后xname又指向enew了,(复制的是地址),而xnew成为垃圾空间。

// void disp(girl x)

void disp(girl &x)                       //定义友元函数,不属于这个类,但在类中声明,注意参数!

{                                               //实际上是通过引用操作类的成员。

       cout<<"girl/'s name is:"<<x.name<<",age:"<<x.age<<endl;

}

void main()

{     girl e("Chen Xingwei",18);

       disp(e);                               //调用友元函数

}

友元函数不是当前类的成员函数,而是独立于当前类的外部函数,但它可以访问该类的所有对象的成员,包括私有成员和公有成员。不用 类名::函数名();

7. //使用一个友元函数访问两个不同的类

#include <iostream.h>

#include <string.h>

class boy;                     //向前引用,否则在下面的const boy会不认识的!

class girl{

       char name[25];

       int age;

public:

       void init(char N[],int A);

       friend void prdata(const girl &plg,const boy &plb);  //声明函数为girl类的友元函数,引用

};                                                           

void girl::init(char N[],int A)

{     strcpy(name,N);

       age=A;

}

 

class boy{

       char name[25];

       int age;

public:

       void init(char N[],int A);

       friend void prdata(const girl &plg,const boy &plb);    //声明函数为boy类的友元函数

};

inline void boy::init(char N[],int A)

{     strcpy(name,N);

       age=A;

}

//void prdata(const girl plg,const boy plb) //const保护数据

void prdata(const girl &plg,const boy &plb) //如上所有改为引用也可,只不过起了外号而已,实际还是同一个对象。而上面的(不包括这个)const girl &plg,const boy &plb可以变为

const girl &,const boy &)声明的问题。

{    

       cout<<"女孩"<<plg.name<<','<<plg.age<<"";

       cout<<"男孩"<<plb.name<<','<<plb.age<<"岁。/n";

}

 

void main()

{     girl G1,G2,G3;

       boy B1,B2,B3;

       G1.init("Stacy",12);

       G2.init("Judith",13);

       G3.init("Leah",12);

       B1.init("Jim",11);

       B2.init("Micheal",13);

       B3.init("Larry",12);

       prdata(G1,B1);

       prdata(G2,B2);

       prdata(G3,B3);

}

一定要谨慎使用,防止对数据的错误操作。

8. // 使用友元成员函数访问另一个类

#include <iostream.h>

#include <string.h>

class girl;               //向前引用(当出现两个及以上类时需要向前引用!)

 

class boy{

       char *name;

       int age;

public:

       boy(char *N,int A)

       {     name=new char[strlen(N)+1];

              strcpy(name,N);

              age=A;

       }

       void disp(girl &);   //声明disp()为类boy的成员函数

       ~boy(){delete name;}

};

class girl{

       char *name;

       int age;

public:

       girl(char *N,int A)

       {     name=new char[strlen(N)+1];

              strcpy(name,N);

              age=A;

       }

       friend void boy::disp(girl &);       //声明类boy的成员函数disp()为类girl的友元函数

       ~girl(){delete name;}

};

void boy::disp(girl &x)

{    

       cout<<"boy/'s name is:"<<name<<",age:"<<age<<endl;  //访问本类对象成员

//     cout<<"boy/'s name is:"<<this->name<<",age:"<<this->age<<endl;//类的成员函数,隐藏this

       cout<<"girl/'s name is:"<<x.name<<",age:"<<x.age<<endl;  //访问友元类对象成员必须指明对象x,因为没有this

}

void main()

{     boy b("chen hao",25);

       girl g("zhang wei",18);

       b.disp(g);

}

说明:

  1. 友元关系是单向的,不具有交换性(我是你的朋友,不能推断出:你是我的朋友)。
  2. 友元关系也不具有传递性(我是你的朋友,你是他的朋友,不能推断出:我是他的朋友)//概念记清,面试所需!

9. //对象作为类的数据成员

#include <iostream.h>

#include <string.h>

class string{

private:

       char *str;

public:

       string(char *s)

       {     str=new char[strlen(s)+1];

              strcpy(str,s);

              cout<<"构造string/n";

       }

       void print(){cout<<str<<endl;}

       ~string()

       {     cout<<"析构string/n";

              delete str;

       }

};

class girl{

private:

       string name;

       int age;

public:

       girl(char *st,int ag):name(st) //注意格式  X::X(参数表0) : 成员名1(参数表1),……,成员名n(参数n)

       {     age=ag;

              cout<<"构造girl/n";

       }

       void print()

       {     name.print();

            cout<<"age:"<<age<<endl;

       }

       ~girl()

       {     cout<<"析构girl/n";

       }

};

void main()

{     girl  obj("Chen hao",25);

       obj.print();

}

main函数开始先新建girl对象obj说明:

  1. 声明一个含有对象成员的类,首先要创建各成员对象。本例在声明类girl中,定义了对象成员:string  name
  2. girl类对象在调用构造函数进行初始化的同时,也要对对象成员进行初始化,因为它也是属于此类的成员。因此在写类girl的构造函数时,也缀上了对对象成员的初始化:

              girl(char *st,int ag):name(st)

       于是在调用girl的构造函数进行初始化时,也给对象成员name赋上了初值。

       这里需要注意的是:在定义类girl的构造函数时,必须缀上其对象成员的名字name,而不能缀上类名,即:

              girl(char *st,int ag):string(st)

       是错误的,因为在类girl中是类string的对象name作为成员,而不是类string作为其成员。

(再次重申: 概念很要,面试所需!)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值