zoukankan      html  css  js  c++  java
  • C++ 笔记

    C++笔记

    1

    推动语言发展的动力是方便和重用

    不是只有面向对象语言可以封装,C语言也可以封装,结构体成员是函数指针的时候也是满足的,但是比较麻烦。

    2类的定义

    类名首字母大写;

    方法名首字母小写

    Class 类名

    {     private:

          public:

    };

     

    3定义成员函数(调用成员函数时必须指定对象和成员名)

    (1)在类中定义成员函数

    类中定义的成员函数一般为内联函数,即使没有明确用

    inline标示;

    在C++中,类定义通常在头文件中,因此这些成员函数

    定义也伴随着进入头文件;

    (2) 在类之后定义成员函数

                         C++允许在其它地方定义成员函数;

    将类定义和其成员函数定义分开,是目前开发程序的

    通常做法。

    我们把类定义看成是类的外部接口,类的成员函数定

    义看成是类的内部实现。

    (3)类成员函数的重载

    重载的定义:两个以上的函数,取相同的函数名,但是形参的个数或者类型不同,编译器根据实参和形参的类型及个数的最佳匹配,自动确定调用哪个函数。

    类的成员函数可以像普通函数一样重载,但是不同类即使有相同的函数名也不算重载。

    4成员函数外部定义的格式

    返回类型  类名::函数名(参数1,参数2……)

    5类的成员的访问

    不管怎么继承,父类私有东西是不能访问的

    1单个类

    类成员可以访问所有;

    单个类实例化对象只能访问共有域public

    2继承

    派生类可以访问父类的public and protected;

    Public继承父类的protected and public 在子类中不变;

    私有继承,父类的protected and public在子类中转换成私有域;

    3保护继承

    父类的protected and public全部转换为protected域;

    多继承只在c++

    成员访问

    (1) 如果是私有的,外部全部不能访问;

    (2) 如果是公有的,普通对象:对象名.成员

    指针对象:对象名->成员

    (3) 静态成员或方法

       Const不可更改可以直接赋值;公有的,类名::静态成员

    (4) 在类中静态成员拥有者是类,静态成员将会只有一个父本

    6

    构造函数的要求:

    (1)函数名必须与类名同名

    (2)构造函数可重载;

    (3)类实例化后系统会自动调用。

    (4)构造函数无返回类型

    (5)构造函数不能被用户调用,只能被系统调用;只能在实例化的时候定义;

    (6)如果不写构造函数编译器会自动添加一个无參的构造函数。一旦你写了构造 函数,系统将不会给他添加

    7

    析构函数:释放内存空间

    (1)没有返回类型,没有参数,不能随意调用,没有重载。只有在类生命期结束的时候,有系统调用。

    (2)析构函数名,就在构造函数名前加上一个“~”,表示“逆构造函数”。

    8

    堆空间

    (1)new:分配堆空间和delete配套使用:释放堆空间。

    (2)new一个对象会自动调用构造函数,delete一个对象会自动调用析构函数,new和delete不需要头文件。

    (3)从堆中分配对象数组:类名 *ps = new 类名[int n];

    (4)释放一个对象数组:delete[]ps;

    (5)使用堆空间的原因:直到运行时才能知道需要多少对象空间;不知道对象的生存期到底有多长;知道运行时才知道一个对象需要多少内存空间。

    9

    构造对象的顺序

    (1)局部和静态对象,以声明的顺序构造;

    (2)静态对象只被构造一次

    (3)所有全局对象都在主函数main()之前被构造

    (4)全局对象构造时无特殊顺序

    (5)成员以其在类中声明的顺序构造

    Class     SA{};

    SA ();无名对象创建之后就会被释放;

    SA  h; 执行到最后才会被释放。

    对于全局对象,是在main函数执行之前调用构造函数的。

    10

    赋值格式:

    类型  类名::静态名 = a;

    静态方法只能访问静态成员,因为他没有this指针。

    New兼容malloc的功能。

    11

    拷贝构造函数:

    (1)可用一个对象去构造另一个对象

    (2)对象作为函数参数传递时,也要涉及对象的拷贝

    (3)class  Stu{;;};

    (4)Stu  fn()(当函数返回一个对象时,要创建一个临时对象以存放返回的对象)

    {

    Stu  ms;//在这里系统调用拷贝构造函数将ms拷贝到新创建的临时对象中

    return ms;

    }

    Int main()

    {

    //Stu  s  =  fn();//浅拷贝

    Stu  s;

    s  =  fn();//深拷贝,拷贝的是资源的内容

    }

    创建的临时对象,在整个创建它们的外部表达式范围内有效,否则无效,也就是说,“s  =  fn();”这个外部表达式,当fn()返回时产生的临时对象拷贝给s后,临时对象就析构了。

    (4)如果类需要析构函数来析构资源,则它也需要一个拷贝函数。

    12

    引用

    C++尽量把引用作为形参

    (1)类型&变量名

    (2)定义之后必须马上初始化:int m;int  &b = m;m和b是等同的,b相当于常量指针一旦确定不能更改。

    (3)一旦初始化之后不可更改,而指针是可以的

    类中的所有的成员函数都可以访问类中全部的成员变量。

    一个类的方法是自身类的有源,有源类的成员方法可以访问私有的变量。

    构造函数可以调用成员函数。

    引用与指针有什么区别?

    1) 引用必须被初始化,指针不必。
    2)
    引用初始化以后不能被改变,指针可以改变所指的对象。
    3)
    不存在指向空值的引用,但是存在指向空值的指针。

    13

    继承(紧耦合)

    子类:修饰符publicprivateprotected)父类名

    定义:

    class  Shape

    {

    private:

    int  m_color;

    proteceted:
           int  m_kind;      

    public:

    void printColor(){printf(“shape color %d ”,m_color);}

    Shape(){printf(“shape class constructed ”);}

    ~Shape(){printf(“shape class destroy ”);}

    };

    class Circle:public Shape

    {

    private:

    float radius;

    public:

    Circle(){printf(“circle class constructed ”);}

    ~Circle(){printf(“circle class destroy ”);}

    void printAera();

    };

    子类继承父类的时候:构造函数先完成父类的构造然后完成子类的构造,析构函数则是先完成子类的释放然后在完成父类的释放。如果是private继承的父类的public和protected域 将变成自己的private域。

    private,protected:

    单个类中:只能是类成员可以访问类的实例化的对象是不可以访问的

    public:全部可以访问

    一层继承(不论是何种继承,类成员可以直接访问 父类的protected,public)

    (1)如果是public

    派生类的实例化对象,访问父类的public但不能访问父类的protected

    (2)如果是private或者是protected

    派生类的实例化对象,不能访问父类的任何域

    如果类中含有别的类对象:

    本类::本类(参数列表):基类名(参数),对象1(参数),对象2(参数)……

    {

    本类的初始化工作;

    }

    14

    多继承

    virtual继承时需要在父类中添加无參的构造函数。

    父类的指针可以指向子类,子类的指针不能指向父类。

    15

    虚函数的作用:允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。

    任何一个类都有一个函数入口表,如果是虚的入口地址将会被更改

    父类指针指向子类,从而使父类能够访问子类的成员。

    虚函数一般不做成内联函数

    纯虚函数:拥有纯虚函数的类是不能实例化的,称为抽象类(Java中的接口)。只要有一个纯虚函数就是抽象类,纯虚函数只能定义指针,指向派生类。

    入口地址表不在内存中,增加虚函数(个数不限)内存大小增加一个指针大小4个字节。

    16 this指针

    《深入浅出MFC》中解释:

     定义类CRect,定义两个对象rect1、rect2,各有自己的m_color成员变量,但rect1.setcolor和rect2.setcolor却都是通往唯一的CRect::setcolor成员函数,那么CRect::setcolor如何处理不同对象的m_color?答案是由一个隐藏参数,名为this指针。当你调用:

    rect1.setcolro(2);

    rect2.setcolor(3);

    时,编译器实际上为你做出来一下的代码:

    CRect::setcolor(2,(CRect*)&rect1);

    CRect::setcolor(3,(CRect*)&rect2);

    多出来的参数,就是所谓的this指针。

    17 指针

    1、指针变量可以有空值,即指针变量不指向任何地址。

    #include “iostream.h”

    int  *p;  p=NULL;

    int  *p;

    p=0;

    2、两指针可以相减,不可相加。若要进行相减运算,则两指针必须指向同一数组,相减结果为相距的数组元素个数

    int   a[10],*p1,*p2;

    p1=a;   p2=a+9;

    p2-p1 :   9  

    3、指向同一数组的两个指针变量可以比较大小:p2>p1

    18

    、有了 malloc/free 为什么还要 new/delete  ?

    malloc 与 free 是 C++/C 语言的标准库函数,new/delete 是 C++的运算符。它们都可用于申请动态内存和释放内存。对于非内部数据类型的对象而言,光用 malloc/free 无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free 是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于 malloc/free。 因此 C++语言需要一个能完成动态内存分配和初始化工作的运算符 new,以及一个能完成清理与释放内存工作的运算符 delete。注意 new/delete 不是库函数。

     

    19  字符串连接1

    #include<stdio.h>

    class CShape{

       private:

           int a;

       public:

        virtual void print(){ printf("CShape= %d ",this->a);}

        virtual void hello() { printf("hello world ");} 

     CShape(int x=3) { a=x;}

    };

    int main()

    {

       CShape obj(10);

       typedef  void (*function)(CShape *thiss);

     

        char *ptr=(char *)&obj;

        int **p=(int **)ptr;

      

        function fpp=(function)(*(*p));

      

        function fpp1=(function)(*(*p+1));

        printf("*******virtaul function pointer** ");

       (*fpp1)(&obj);

       (*fpp)(&obj);

       printf("*******object call function** ");

       obj.hello();

       obj.print();

      

    }

    20 字符串连接2

    #include <iostream>

    using namespace std;

    class String

    {

           public:

                  String()

                  {

                         this->str=NULL;

                  }

                  String(char *s)

                  {

                         str=(char *)malloc(sizeof(s));

                         memset(str,0,sizeof(s));

                         strcpy(str,s);

                  }

                  String operator+(const

                                String& s)

                  {

                         String str3;

                         str3.str=(char *)malloc(sizeof(s.str)+sizeof(this->str));

                         memset(str3.str,0,sizeof(str3.str));

                         strcat(str3.str,this->str);

                         strcat(str3.str,s.str);

                         return str3;

                  }

                    void operator=(const String &s1)

                  {

                         if(this->str!=NULL)

                                free(this->str);

                         this->str=(char *)malloc(sizeof(s1.str));

                         strcpy(this->str,s1.str);

                         //return *this;

                  }

                  friend String operator++(String &thiss)

                  {

                         int i=0;

                         while(thiss.str[i]!='')

                         {

                                thiss.str[i]+=1;

                                i++;

                         }

                  }

                  void print()

                  {

                         cout<<str<<endl;

                  }

                  ~String()

                  {

                         if(str!=NULL)

                                free(str);

                  }

           private:

                  char *str;

    };

    int main()

    {

           String s1("hello"),s2("world"),s3;

           s3 = s1+s2;

           s3.print();

           return 0;

    }

  • 相关阅读:
    Effective Java 第三版——72. 赞成使用标准异常
    Effective Java 第三版——71. 避免不必要地使用检查异常
    Effective Java 第三版——70. 对可恢复条件使用检查异常,对编程错误使用运行时异常
    Effective Java 第三版——69. 仅在发生异常的条件下使用异常
    Effective Java 第三版——68. 遵守普遍接受的命名约定
    Effective Java 第三版——67. 明智谨慎地进行优化
    Effective Java 第三版——66. 明智谨慎地使用本地方法
    Effective Java 第三版——65. 接口优于反射
    Effective Java 第三版——64. 通过对象的接口引用对象
    Effective Java 第三版——63. 注意字符串连接的性能
  • 原文地址:https://www.cnblogs.com/3ddan/p/3288188.html
Copyright © 2011-2022 走看看