c++学习笔记:类和结构体

  1. 空类的大小是1。
  2. 在默认情况下,类中的成员(包括数据和函数)都是私有的,结构体中的成员在默认情况下都是公有的。
  3. 构造函数是在初始化的时候调用的,只能有一个默认构造函数,
  4. 静态数据成员(static)
    (1)静态数据成员是类的一个成员,同一个类中所有对象共享该变量,
    (2)静态数据成员不依赖对象而存在,在对象之前已经存在,类的大小计算不包括静态变量
    (3)静态数据成员的生存周期和整个程序的生存期一样
    (4)静态数据成员在类的内部进行说明,必须在类的外部进行定义,否则编译出错
  5. 静态成员函数(static)
    (1)静态成员函数和静态数据成员类似,在对象生成之前已经存在。
    (2)只能访问类中定义的静态成员,其他数据可以以参数形式传到静态函数中。
  6. 友元函数既可以是一个外部函数,也可以是另外一个类的函数成员,他可以访问类中定义的私有成员,关键字friend。
  7. 拷贝构造函数
    1. 是一个特殊的构造函数,当定义一个对象并采用同类型的另外一个对象初始化时,将自动调用拷贝构造函数。
    2. 拷贝构造函数的参数一定是一个引用。如果他的形参只是一个普通的局部对象,则在传参的时候又会调用拷贝构造函数,引起循环调用,直到内存耗尽。

      ClassName (ClassName &obj){}
  8. 运算符重载

    1. 重载赋值运算符

      ClassName operator = (const ClassName &right){……;return *this;}

      注意:右边的参数不一定是常引用,引用的好处是防止传参时候生成拷贝对象,减少时间空间。

    2. 重载前置++运算符,++n

      ClassName operator ++(){}
    3. 重载后置++运算符, n++

      ClassName operator ++(int){}

      注意:后置++运算符中参数只有类型而没有名称,是一个哑元。

    4. 重载类型转换运算符

      operator float(){float temp;;return temp;}
    5. 重载流运算符(<< , >>)

      friend ostream &operator <<(ostream &strm, ClassName &obj)(strm<<obj;return strm;)
      friend istream &operator >>(istream &strm, ClassName &obj)(strm>>obj;return strm;)

      上诉函数告诉c++如何处理下列形式的表达式:
      ostream_obj << ClassName_obj
      注意:这两个操作符分别定义在ostream和istream类中,因此需要通过友元函数的形式实现函数重载。cout和cin分别是ostream和istream类的对象。函数的返回值之所以是一个Ostream对象,是为了处理如下级联调用形式的语句:
      cout<<Class_obj1<<Class_obj2<<endl;

  9. 继承、多态和虚函数

    继承是已有类的基础上创建新类,多态是指类中具有相似功能的不同函数采用同一个名称来实现。

    1. 构造函数

      如果类存在继承关系,派生类必须在其初始化表里调用基类的构造函数。初始化表中调用构造函数,如下例:

      B::B(int x, int y): A(x) // 在初始化表里调用A的构造函数
      {…}

      成员对象初始化的次序完全不受它们在初始化表中次序的影响,只由成员对象在类中声明的次序决定。这是因为类的声明是唯一的,而类的构造函数可以有多个,因此会有多个不同次序的初始化表。如果成员对象按照初始化表的次序进行构造,这将导致析构函数无法得到唯一的逆序。
      定义一个子类对象,先调用基类的构造函数,再调用子类的构造函数,析构函数的调用顺序相反。

    2. private protected public
      • private成员只能被本类成员(类内)和友元访问,不能被派生类访问。
      • protected成员可以被派生类访问,不能被程序其他部分访问。
      • public继承:基类public成员,protected成员访问属性在派生类中分别变成:public, protected,private
      • protected继承:基类public成员,protected成员的访问属性在派生类中分别变成:protected, protected,基类的privilege成员不能再子类中访问
      • private继承:基类public成员,protected成员的访问属性在派生类中分别变成:private, private, private
      • 如果省略了继承修饰符,那么就是私有继承
    3. 指向基类的指针
      • 指向基类对象的指针可以指向其子类对象,但基类指针指向子类对象时,所访问的任然是基类中的成员。
      • 如果子类覆盖了基类的成员(函数成员或变量),但通过该基类指针所访问的成员任然是基类成员,而不是子类成员
      • 反过来不行,指向子类对象的指针不能指向基类对象。
  10. 重载、覆盖(重写)、隐藏区别

    1. 重载, 参数不同的同名函数,不关心返回值。并不是两个函数的名字相同就能构成重载。全局函数和类的成员函数同名不算重载,因为函数的作用域不同。对于函数重载,out(float a)和out( int a) 当调用 out(1)时,是正确的, 当调用out(0.5)时,编译错误,因为编译器无法确定应该如何进行类型转换。
    2. 隐藏, 是指派生类的函数屏蔽了与其同名的基类函数,注意只要同名函数,不管参数列表是否相同,基类函数都会被隐藏。
    3. 覆盖, 重写的基类中被重写的函数必须有virtual修饰,覆盖是c++多态的部分体现。
    4. 函数重载只是动态的多态性,在编译阶段,给不同的函数不同的函数名,而虚函数实现运行时多态。
    5. 虚函数是c++多态的真正体现
  11. 虚函数,纯虚函数

    1. 虚函数是一个成员函数,唯一要求是子类中一定要覆盖他。对于虚函数,编译器完成的是动态绑定,即对函数的调用是在运行时确定的。这样在调用父类的方法时,该方法中的函数调用是动态的,即会调用子类中重写的函数,而不是父类中的函数。
    2. 纯虚函数在基类中没有函数体,要求在子类中一定要覆盖它。有纯虚函数的类称为抽象类,不能定义对象。
  12. 模板,类模板

常用结构体

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};
/*****************************
Definition for an interval.
******************************/
struct Interval {
    int start;
    int end;
    Interval() : start(0), end(0) {}
    Interval(int s, int e) : start(s), end(e) {}
};
/*****************************************
 Definition for a binary tree node.
******************************************/
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
发布了19 篇原创文章 · 获赞 6 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/u010548772/article/details/79446036