C++学习笔记2022.3.22

2022.3.22

类成员,类的组合,友元

  1. 常对象只能调用它的常成员函数,而不能调用普通的成员

    #include<iostream>   //例3.40-2
    using namespace std;
    class Sample{
     private:
      int n;
     public:
      int m;
       Sample(int i,int j){ m=i; n=j; } 
       void setvalue(int i){ n=i; }
       void disply()
      {cout<<"m="<<m<<endl; 
       cout<<"n="<<n<<endl; } };
    int main()
    {const Sample a(10,20);
       a.setvalue(40);           
       a.m=30;
       a.disply();  return 0;}
    
    

    所以setvalue()方法不能使用

    同时,常对象即便是public数据成员也不能直接修改,

  2. 常函数的说明格式:

    类型说明符 函数名(参数表)const;
    

    声明带const , 使用不需要,同时,常成员函数不能更新对象的数据成员的值

    #include<iostream>   //例3.40-2
    using namespace std;
    class Sample{
     private:
      int n;
     public:
      int m;
       Sample(int i,int j){ m=i; n=j; }
       void setvalue(int i){ n=i; }
       void disply() const
      {cout<<"m="<<m<<endl;
       cout<<"n="<<n<<endl; } };
    int main()
    {const Sample a(10,20);
       a.disply();  return 0;}
    
    #include<iostream>   //例3.40-2
    using namespace std;
    class Sample{
     private:
      int n;
     public:
      int m;
       Sample(int i,int j){ m=i; n=j; }
       //void setvalue(int i){ n=i; }
       void disply() ;
       void disply() const ;
    };
    void Sample::disply()  {
        cout<<"another";
    }
    void Sample::disply() const
    {cout<<"m="<<m<<endl;
        cout<<"n="<<n<<endl; }
    int main()
    {const Sample a(10,20);
       a.disply();
       Sample b (20,30);
       b.disply();
       return 0;}
    

    注意下,class最后花括号后面要加个分号

  3. 使用const说明的数据成员称为常数据成员。
    如果在一个类中说明了常数据成员,那么构造函数就只能通过初始化列表对该数据成员进行初始化, 而不能采用在函数中直接赋值的方法

    #include<iostream>   //例3.40-2
    using namespace std;
    class Sample{
     private:
      const int n,a,b;
     public:
      const int m;
       //void setvalue(int i){ n=i; }
       Sample(int n,int a,int b,int m);
       void disply() ;
       void disply() const ;
    };
    Sample::Sample(int n, int a, int b, int m):n(n),a(a),b(b),m(m)
    {}
    void Sample::disply()  {
        cout<<"another";
    }
    void Sample::disply() const
    {cout<<"m="<<m<<endl;
        cout<<"n="<<n<<endl; }
    int main()
    {const Sample a(10,20,30,40);
       a.disply();
       Sample b (10,90,20,30);
       b.disply();
       return 0;}
    

    才发现,c++参数列表貌似就是java中this.a=a这个操作,像下面三种,第一种完全达到目的,第二种第三种都得到垃圾值

    #include<iostream>   //例3.40-2
    using namespace std;
    class Sample{
     private:
      const int n,a,b;
     public:
      const int m;
       //void setvalue(int i){ n=i; }
       Sample(int n,int a,int b,int m);
       void disply() ;
       void disply() const ;
    };
    Sample::Sample(int n, int a, int b, int m):n(n),a(a),b(b),m(m)
    {}
    void Sample::disply()  {
        cout<<"another";
    }
    void Sample::disply() const
    {cout<<"m="<<m<<endl;
        cout<<"n="<<n<<endl; }
    int main()
    {const Sample a(10,20,30,40);
       a.disply();
       Sample b (10,90,20,30);
       b.disply();
       return 0;}
    
    #include<iostream>   //例3.40-2
    using namespace std;
    class Sample{
    private:
         const int n,a,b;
    public:
         const int m;
        //void setvalue(int i){ n=i; }
        Sample(int n,int a,int b,int m);
        void disply() ;
        void disply() const ;
    };
    Sample::Sample(int n, int a, int b, int m)
    {
        n=n;
        m=m;
        a=a;
        b=b;
    }
    void Sample::disply()  {
        cout<<"another";
    }
    void Sample::disply() const
    {cout<<"m="<<m<<endl;
        cout<<"n="<<n<<endl; }
    int main()
    {const Sample a(10,20,30,40);
        a.disply();
        Sample b (10,90,20,30);
        b.disply();
        return 0;}
    
    #include<iostream>   //例3.40-2
    using namespace std;
    class Sample{
     private:
        int n,a,b;
     public:
      int m;
       //void setvalue(int i){ n=i; }
       Sample(int n,int a,int b,int m);
       void disply() ;
       void disply() const ;
    };
    Sample::Sample(int n, int a, int b, int m)
    {
        n=n;
        m=m;
    }
    void Sample::disply()  {
        cout<<"another";
    }
    void Sample::disply() const
    {cout<<"m="<<m<<endl;
        cout<<"n="<<n<<endl; }
    int main()
    {const Sample a(10,20,30,40);
       a.disply();
       Sample b (10,90,20,30);
       b.disply();
       return 0;}
    
  4. 总结一下,

    普通成员函数常成员函数
    普通数据成员可以访问,也可以改变值可以访问,但不可以改变值
    常数据成员可以访问,但不可以改变值可以访问,但不可以改变值
    常对象的数据成员不允许访问和改变值可以访问,但不可以改变值
  5. 定义静态数据成员的格式如下:

         static 数据类型 数据成员名;
    
    #include<iostream>   //例3.40-2
    using namespace std;
    class Sample{
        static int c;
    private:
        int n,a,b;
    public:
        int m;
        //void setvalue(int i){ n=i; }
        Sample(int n,int a,int b,int m);
        void disply() ;
        void disply() const ;
    };
    int Sample:: c =79898;
    Sample::Sample(int n, int a, int b, int m):n(n),a(a),b(b),m(m)
    {}
    void Sample::disply()  {
        cout<<"another";
    }
    void Sample::disply() const
    {cout<<"m="<<m<<endl;
        cout<<"n="<<n<<endl;
        cout<<"c="<<c<<endl;
    }
    int main()
    {const Sample a(10,20,30,40);
        a.disply();
        Sample b (10,90,20,30);
        b.disply();
        return 0;}
    
  6. 静态数据成员的初始化要在main()函数之前,类定义之外

  7. 值得注意,下面这种写法没什么问题(我个人觉得挺离谱的),因为对象的声明的

    #include<iostream>   //例3.40-2
    using namespace std;
    class Sample{
    private:
        int n,a,b;
    public:
        static int c;
        int m;
        //void setvalue(int i){ n=i; }
        Sample(int n,int a,int b,int m);
        void disply() ;
        void disply() const ;
    };
    Sample::Sample(int n, int a, int b, int m):n(n),a(a),b(b),m(m)
    {}
    void Sample::disply()  {
        cout<<"another";
    }
    void Sample::disply() const
    {cout<<"m="<<m<<endl;
        cout<<"n="<<n<<endl;
        cout<<"c="<<c<<endl;
    }
    int Sample:: c =79898;
    const Sample a(10,20,30,40);
    int main()
    {
        cout<<Sample::c;
        a.disply();
        Sample b (10,90,20,30);
        b.disply();
        return 0;
    }
    
    #include<iostream>   //例3.40-2
    using namespace std;
    class Sample{
    private:
        int n,a,b;
    public:
        static int c;
        int m;
        //void setvalue(int i){ n=i; }
        Sample(int n,int a,int b,int m);
        void disply() ;
        void disply() const ;
    };
    Sample::Sample(int n, int a, int b, int m):n(n),a(a),b(b),m(m)
    {}
    void Sample::disply()  {
        cout<<"another";
    }
    void Sample::disply() const
    {cout<<"m="<<m<<endl;
        cout<<"n="<<n<<endl;
        cout<<"c="<<c<<endl;
    }
    int Sample:: c =7000000;
    const Sample a(10,20,30,40);
    int main()
    {
        Sample:: c =79898;
        cout<<Sample::c;
        a.disply();
        Sample b (10,90,20,30);
        b.disply();
        return 0;
    }
    

    我稍微修改了下,静态数据成员能这么写估计是因为public了,所以声明对象以后又将c的值修改了下,不过这种延后感觉有点不太协调.

  8. 若静态成员函数需要访问非静态成员,静态成员函数只能通过对象名(对象指针或引用)访问该对象的非静态成员

    这个其实挺好理解的,因为静态成员函数在对象声明前存在,所以必须得有引用或者指针或者对象才可以调用函数.(注意下,对象我指的是直接在函数里初始化得到的一个,而指针引用我指的其实是在形参列表处的)

  9. 如何给组合类中的对象成员初始化

    class  X {
       类名1  对象成员名1;
       类名2  对象成员名2;
               …
       类名n  对象成员名n;
     };
    
      X∷X(参数表0):对象成员名1(参数表1),对象成员名2
           (参数表2),…,对象成员名n(参数表n) 
      {
         类X的构造函数体
      }
    

    表现形式

     class A {  //.. ..   };
     class B {  //.. ..   }; 
     class C {  //.. ..   }; 
     class D {
        A  a;     
        B  b;
        C  c;
       public:
        D(参数表0):a(参数表1),b(参数表2),c(参数表3)
        {    // …构造函数体 }
     } ;
    
    
  10. 如何用友元函数

    #include<iostream>   //例3.40-2
    using namespace std;
    class Sample{
    private:
        int n,a,b;
    public:
        static int c;
        int m;
        //void setvalue(int i){ n=i; }
        Sample(int n,int a,int b,int m);
        void disply() ;
        void disply() const ;
        friend void fun(Sample &w);
    };
    Sample::Sample(int n, int a, int b, int m):n(n),a(a),b(b),m(m)
    {}
    void fun(Sample & w){
        cout<<w.c;
    }
    
    void Sample::disply()  {
        cout<<"another";
    }
    void Sample::disply() const
    {cout<<"m="<<m<<endl;
        cout<<"n="<<n<<endl;
        cout<<"c="<<c<<endl;
    }
    int Sample:: c =79898;
    int main()
    {
        Sample b (10,90,20,30);
        fun(b);
        return 0;
    }
    

    注意下,友元函数不能用const变成常成员函数,也就是友元函数不能处理常对象

    友元函数最大的特点就是,不需要对象或者类的格式就可以直接使用,比较像c语言,至于破坏封装,我其实我现在还没感觉到

    一个函数可以是多个类的友元函数。当一个函数需要访问多个类时,友元函数非常有用,不过这样会非常混乱,改bug可以玩死你,修改个数据也会死的挺惨的

  11. 将其它类成员函数声明为本类友元函数
    一个类的成员函数也可以作为另一个类的友元,这种成员函数称为友元成员函数。
    定义友元成员函数目的:使两个或多个类相互合作、协调工作,完成某一任务。

    成员函数可以访问自己类的对象,不需要引用,然后访问别的类的对象时,则需要

  12. 友元类的说明方法是在另一个类声明中加入语句:

    friend  类名;
    
     class  Y {
          …
        };
        class X {
          …
          friend  Y;
          …
        };
    
    

    友元类的一个特点就是Y中的所有函数对于X都是友元函数

  13. string类的直接复制是深拷贝,复制的字符串修改并不影响前面被拷贝的字符串

    #include <string>
    #include <iostream>
    using namespace  std;
    int main(){
        std::string a ="abcd";
        std::string b =a;
        cout<<&a<<endl;
        cout<<&b<<endl;
        std::cout<<a<<std::endl;
        cout<<b<<endl;
        b[0]='h';
        cout<<&a<<endl;
        cout<<&b<<endl;
        cout<<a<<endl;
        cout<<b<<endl;
    }
    
  14. 一段有意思的代码

    #include <string>
    #include <iostream>
    using namespace  std;
    class A {
    private:
        int a;
    public:
        A(int a);
        void display();
    };
    A::A(int a) :a(a){
        cout<<"first"<<endl;
    }
    
    void A::display() {
        cout<<a;
    }
    int main(){
        A a =10;
        A b = a;
        a.display();
        b.display();
        return 0;
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cjz-lxg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值