C++从入门到精通(三)

C++学习第3章

将自己觉得尤其重要,或以前没了解获得新技巧进行加粗,重点复习

3-1 成员函数,对象拷贝,私有成员

1. 内容回顾
  • 类对象访问内部成员用c.variable;
  • 指针类访问内部成员用p->variable;
2. class内部成员默认为private类型;struct内部默认为public类型。
3. 对象的拷贝
   Student s1;
   s1.age=10;
   s1.name="zhang_san";

    //四种拷贝方式
   Student s2=s1;
   Student s3(s1);
   Student s4{s1};
   Student s5={s1};

3-2 构造函数详解,explict,初始化列表

1. 构造函数所有变量最好都初始化,以免引起未赋值的变量以后造成不可预估的错误
2. 多个构造函数
  • 类可以定义多个构造函数,每个构造函数有不同个数的输入值;
  • 类初始化的几种方式
Student s1=Student{"zhangsan",12,1};
Student s2{"zhangsan",12,1};
Student s3={"zhangsan",12,1};
Student s1=Student("zhangsan",12,1);
Student s2("zhangsan",12,1);
3. 对象拷贝几种方式
TIme t1;
Time t2=t1;
Time t3(t1);
Time t4{t1}
Time t5={t1};
  • 以上t2-t5的 对象拷贝不会调用传统意义上的构造函数,其调用的是拷贝构造函数
4. 函数变量默认值应该写在函数声明中; 函数定义时不能加入,除非函数没有声明。
  • 函数内部变量的声明,如果一个变量引入了默认值,那其右侧的变量必去也全部存在默认值!!
  • 示例加使用:
class.h
void Time(string name,int age=20, bool gender=0);

class.cpp
void Time(string name,int age, bool gender)
{
   ...
}

int main()
{
   Time t("zhangsan");//后面的参数可以不再写入,系统会使用默认值。
}
  • 函数没有声明的情况下
void fun(int a,int b=0)
{...}
int main()
{
   int a=9;
   int b;
   fun(a,b);
   return 0;
}
5. 隐式转换和explict
  • 含糊不清的写法,存在临时对象或者隐式转换问题;
class Time
{
   int hour;
   int minute;
   Time(int a);
};
//
Time::Time(int a)
{
   minute=10;
   hour=a;
}
int main()
{
   Time t=13;//隐式转换为类类型。
}
  • 可以强制系统,要求构造函数不能做隐式类型转换。 单参数的函数一般都加上explicit限制
explicit void set_value(int a);//只在函数声明前加
void set_value(int a)
{...}
6. 构造函数初始化列表
Time::Time(int h,int m, int s):hour(h),minute(m),second(s){}

3-3 inline,const,mutable,this ,stat

1. 类的inline函数
  1. 在类的.h文件中就定义好的函数,被编译器自动视为inline函数,但前提是函数定义足够短小。非inline函数是不能在.h文件中定义的,因为多次Include头文件时会出现重定义错误。
void obtain_value(){return value;}
2. 常量成员函数:函数声明和定义后面都需要加const.
  1. 作用:该成员函数内部不会修改任何成员变量的值。
int obtain_value() const;
3. 新建一个const 类对象,只能调用声明为const的函数,即在屁股后面加const的函数。不能调用其余普通函数
  • 普通函数,即不是类的函数后面不能加const.
 const Time tt;
 tt.change_value(6);//错误!不允许。 
 tt.obtain_value();//允许。
4. mutable 加在变量前面,可以实现const函数内修改其值。适用于:const对象定义后,又需要修改其内部某个变量的情况下。
class Time{
mutable int test_value=0;

int obtain_value() const;
}int Time::obtain_value() const
{
   test_value+=1;
   return test_value;
}
5. this 返回自身对象的引用
  • this指针只能在类成员函数中使用,全局函数,静态函数都不能使用;
  • 在成员函数中,this为指向该对象的const指针,不能被修改。成员函数内this 所存储的地址,就是调用该函数的类的地址。
6. 静态变量
  1. 普通变量未赋初值,系统会随便给一个值,静态变量系统会默认赋值为0。
  2. 静态变量存储在静态存储区,储存上一次调用后留下的值。
  3. 全局静态变量和局部静态变量区别
    1. 全局静态变量,表示该变量只能在该cpp文件全域中使用,但是不能被其他cpp文件中使用; 局部静态变量一般表示函数内定义的变量,只能在函数内部用
static int test=10;//全局变量
int fun(){static int b=10; return b+1;}
  1. C语言中不同cpp文件之间内部的函数和变量之间的调用规则
    • 如果变量int test=10;在p1.cpp中定义,在p2.cpp中也想使用的话,则在p1.cpp中使用语句:extern int test; 然后就可以直接用test了。
    • 如果函数fun()在p1.cpp中定义,但是想在p2.cpp中使用的话,只许在p2.cpp中重新声明一下函数即可,即void fun();然后就可以直接使用了。
  2. 在类内的变量和函数加static,属于整个类的成员函数,调用时类名::成员函数名();注意:静态成员函数只能操作静态成员变量。
    1. 在类内定义的静态变量,不能给初值,因为此时只是声明,还没有分配内存。为了能够使用,必须定义静态成员变量
      1. 一般会在某一个cpp文件开头来定义,注意,只定义1次即可,定义以后才可以使用。
      2. test值若重新定义为30,那么只要后续不修改,任何新定义的Time类对象的变量test值均为30,且这些变量都具有相同的地址值。
      3. 静态函数,实现的时候不用再加static,与函数const不同。静态函数只能操作静态成员变量,不能操作其他普通变量。静态函数的调用也有两种方式:
class Time
{
   public:
   static int test;
   static void fun_test();
};

void Time::fun_test()
{
   test+=1;
   return;
}
//01.cpp

//静态成员变量定义
int Time::test=10;//定义的时候不用再加static。此时不给初值的话,系统会默认赋值为0.
int main()
{
   //静态变量调用方法一
   cout<<Time::test<<endl;

   //调动方法二
   Time my_time1;
   my_time1.test=30;
   cout<<my_time1.test<<endl; 

   //静态函数调用方法一
   Time::fun_test();
   //静态函数调用方法二
   Time my_time2;
   my_time2.fun_test();
    return 0;
}
int fun()
{
   static int b;
   b+=1;
   return b; 
}

int main()
{
   //a1=1;
   int a1=fun();
   //a2=2;
   int a2=fun();
   //a3=3;
   int a3=fun();
   ...
}

3-4 类内初始化、默认构造函数、=default

3-5 拷贝构造函数

3-6 重载运算符,拷贝赋值运算符析构函数

3-7 派生类,调用顺序,访问登记,函数遮蔽

3-8 基类指针、虚纯虚函数、多态性、虚析构

友元函数、友元类,友元成员函数

RTTI、dynamic_cast、typeid、虚函数表

基类与派生类关系的详细再探讨
左值、右值、左值引用、右值引用、move
临时对象深入探讨,解析,提高性能手段

对象移动,移动构造函数,移动赋值运算符

继承的构造函数,多重继承,虚继承

类型转换构造函数,运算符,类成员指针

你可能感兴趣的:(C++和C语言)