C++复习笔记

C++复习整理

  • 允许用0B或0b作为前缀表示二进制数字(0B10010=37)

  • 八进制十进制每3位添加一个’(分隔符),二进制十六进制每4位添加一个

  • 进制转换:(1条消息) 计算机基础进制转换(二进制、八进制、十进制、十六进制)_戴翔的技术博客-CSDN博客_计算机进制

  • ‘\b’的作用:输出到7时遇到3个\b,光标向前移动三个到3后面,输出89覆盖后面的45(如果光标遇到\n则停止移动)

         #include <stdio.h>
         int main(void)
         {
             printf("1234567\b\b\b\b89");     //输出1238967
             return 0;
         }
    
  • 自定义字面值(后缀必须以_开头)

    #include<iostream>
    using namespace std;
    typedef unsigned long long ull;
    ull operator""_km(ull n)
    {
        return n * 1000000;
    }
    int main()           //输出disetace is:12000000mm
    {
        cout << "disetace is:" << 12_km << "mm" << endl;
        return 0;
    }
    
  • cin.get()具备读取空白字符,以及包含空白字符的字符串的能力,会接受缓存区的字符,如果上一行有\n则会被接受,程序出现bug。也可以暂停程序,等待用户输入任意键继续。

  • cin.getline()函数也具有类似于cin.get()的作用可以接收空白字符,但是遇到换行符会终止输入,并不会影响输出结果。超过规定字符数字时需要用cin.clear()函数重新打开输入流。再次正确使用cin.getline()输出后面的字符。

  • cin.gcount()返回上一次cin输入的字符个数(针对get,getline,read)

  • cin.ignore()舍弃缓冲区中的字符,cin.ignore(100,\n )忽略缓冲区中前100个字符,遇到\n停止。

  • boolalpha

引用(给变量起别名):数据类型 &别名=原名

  • 引用必须初始化:int &b;(×)

  • 引用一经初始化便不可修改,即不能当作另一个数据的别名

  • 不要返回局部变量的引用

  • 函数的调用可以作为左值

    #include<iostream>
    using namespace std;
    //test01为返回局部变量的引用
    int& test01()
    {
        int a = 10;
        return a;
    }
    //test02:如果函数返回值是引用,则该函数的调用可以作为左值使用
    int& test02()
    {
        static int a = 10;  //static:将a存放至全局区,不会被释放
        return a;
    }
    int main()
    {
        int& ref01 =test01();
        cout << ref01 << endl;
        cout << ref01 << endl;  //此时a已经被释放,无法显示正确的结果
        int& ref02 = test02();
        cout << ref02 << endl;  
        cout << ref02 << endl;  //static:作为全局变量后,a的值不再发生更改
        test02() = 100;  //相当于a=100
        cout << ref02 << endl;
        cout << ref02 << endl;  
        return 0;
    }
    
    
  • 引用的本质:指针常量

    int &ref=10   //error
    const int &ref=10  //true 但是ref只读不可修改
    
  • const修饰形参防止误操作

    #include<iostream>
    using namespace std;
    void showVal(int &val) //只要求打印不改变原参数则可以改成showVal(const int &val)
    {
        val = 100; //当引用作为形参时可以在函数中进行修改,此时主函数中的a也会发生改变
        cout << "val=" << val << endl;  
    }
    int main()
    {
        int a = 10;
        showVal(a);
        cout << "a=" << a << endl; //输出val=100,a=100
        return 0;
    }
    

函数

  • 函数可以设置默认参数

    #include<iostream>
    using namespace std;
    //int add(int a=10,b=10,c=10);如果函数声明设定了默认值,下方函数的实现就不能设置
    int add(int a, int b=20, int c=30) //给b设定默认值后,b后面的数都必须有默认值
    {
    	return a + b + c;
    }
    int main()
    {
    	cout<<add(10, 30);  //自己传入的b是30,但是函数参数为20此时取调用时的数
    	return 0;   //输出70
    }
    
  • 占位参数

    #include<iostream>
    using namespace std;
    void func(int a, int) //两种方式都可,但是此后只有第一个数据可以使用
    {         //可以改为void func(int a,int =1;)下面第二个就不必再传(默认参数)
    	cout << "占位参数" << endl;
    }
    int main() {
    	func(1, 1);//必须传入数据
    	return 0;
    }
    
  • 函数重载:可以让函数名相同,提高复用性

    • 满足条件

      • 在同一个作用域下
      • 函数名称相同
      • 函数参数 类型不同 或者 个数不同 或者顺序不同
    • 函数返回值不可以作为重载的条件

      int func(int a,double b);
      void func(int a,double b);  //error
      
    • 函数引用可以作为重载的条件使用

      void func(int &a);  //int a;func(a)
      void func(const &a);//func(10)
      
    • 函数重载遇到默认参数时

      void func(int a ,int b=10);
      void func(int a);              //error
      
  • 三种访问权限

    • 公共权限 public:类内类外都可以访问
    • 保护权限protected:类内和子类可以访问,类外不可以
    • 私有权限private:类内可以访问
  • c++中strucct和class唯一的区别:struct默认权限为公共,class默认权限为私有

  • set、get访问器:(还可以判断用户输入数字的有效性)

#include<iostream>
using namespace std;
class Stdent
{
public:
	void setName(string name) //设置姓名
	{
		s_name = name;
	}
	string getName()  //获取姓名
	{
		return s_name;
	}
private:
	string s_name;
};
int main()
{
	Stdent std;
	std.setName("th");
	cout<<"姓名:"<<std.getName()<<endl;
}
  • 父类中所有非静态成员属性子类都可以继承。私有成员子类也可以继承,但是被编译器隐藏了访问不到。
  • 构造函数:主要作用于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无需手动调用。
    • 没有返回值,也不写void
    • 函数名称与类名相同
    • 构造函数可以有参数,因此可以发生重载
    • 在调用对象时会自动调用构造,且智慧调用一次
  • 析构函数:对象消亡时,自动被调用,用来释放对象占用的空间
    • (在main函数中可能看不到析构函数的调用,因为窗口关闭构造函数销毁时才会调用)
    • 名字与类名相同
    • 在前面需要加上"~"
    • 无参数,无返回值(不可以发生重载)
    • 一个类最多只有一个析构函数
    • 不显示定义析构函数会调用默认析构函数(缺省析构函数)
  • 拷贝函数调用时机:
    • 使用一个已经创建完毕的对象来初始化一个新对象
    • 值传递的方式给函数参数传值
    • 以值方式返回局部对象
  • 用户定义有参构造函数时,c++不再提供默认无参构造,但是会提供默认拷贝函数
  • 用户只提供拷贝函数时,c++不再提供默认无参构造
  • 匿名对象:构造一个有返回值的构造函数后,类名(参数);,构造函数使用之后将会立即使用虚构函数。
  • 浅拷贝:简单的赋值拷贝操作
    • 堆区的内存会重复释放
  • 深拷贝:在堆区重新申请空间,进行拷贝操作。
  • 静态成员变量
    • 所有对象共享同一份数据
    • 在编译阶段分配内存
    • 类内声明,类外初始化
class Person
{
public:
	static int m_A;   //类内声明
};
int Person::m_A=100; //类外初始化
  • 静态成员变量仍然有访问权限,如果设置在私有权限下,类外就不能访问

  • 因为静态变量不属于任何对象,所有对象共享这一份所有有两种访问方式

    //  1
    Person p;
    cout<<p.m_A<<endl;
    //  2
    cout<<Person::m_A<<endl;
    
  • 静态成员函数

    • 所有对象共享同一个函数
    • 静态成员函数只能访问静态成员变量
  • 空类占一个字节

  • 在这里插入图片描述

  • this指针是隐含在每一个非静态成员函数内的一种指针:指向 被调用的成员函数 所属的对象

    • 解决名称冲突

    • 返回对象本身用*this

    • #include<iostream>
      using namespace std;
      class Person
      {
      public:
      	Person(int age)
      	{
      		this->age = age;
      	}
      	Person& personAdd(Person& p)   //返回本体时用引用的方式返回(重点)
      	{
      		this->age += p.age;  
      		return *this;
      	}
      	int age;
      };
      int main()
      {
      	Person p = 10;
      	Person p1 = 10;
      	p1.personAdd(p).personAdd(p).personAdd(p); //此时能够重复调用此函数(链式编程思想)
      	cout << "p1的年龄是" << p1.age << endl;
      	return 0;
      }
      
  • 空指针可以访问成员函数,但是访问涉及this->的成员函数时this指针为空,会报错

    void showPersonAge()
    {
        if(this==NULL)
        {
       		return ;    //这样处理
        }
        cout<<"age = "<<this->m_Age<<endl;//this指针传入为空
    }
    
  • const修饰成员函数(常函数)

    • 在这里插入图片描述

    • 常对象只能调用常函数,因为普通成员函数可以修改属性

  • 友元函数:让一个函数或者类访问另一个类中的私有成员

    • 全局函数做友元
    • 类做友元
    • 成员函数做友元(友元的三种实现)
  • 只能利用全局函数重载左移运算符(成员函数无法实现cout在左边输出)

  • 运算符重载

    #include<iostream>
    using namespace std;
    
    class Person
    {
    	friend ostream& operator<<(ostream& cout, Person& p);
    public:
    	Person operator+(Person &p)
    	{
    		Person tep(0,0);
    		tep.m_A=this->m_A + p.m_A;
    		tep.m_B=this->m_B + p.m_B;
    		return tep;
    	}
    	Person(int a,int b)
    	{
    		this->m_A = a;
    		this->m_B = b;
    	}
    private:
    	int m_A;
    	int m_B;
    	
    };
    //左移运算符
    ostream& operator<<(ostream&cout, Person& p)
    {
    	cout << p.m_A << endl;
    	cout << p.m_B << endl;
    	return cout;
    }
    
    int main()
    {
    	Person p1(10, 20);
    	Person p2(0,0);
    	p2 = p1 + p1;
    	cout << p2 << endl;
    	return 0;
    }
    
  • 继承中先构造父类再构造子类,析构顺序相反

  • 子类和父类中出现同名的成员时直接访问是子类的成员,如果要访问父类需要添加作用域:son.data(子类) son.dad::data(父类)

  • 子类不会继承父类的构造函数,只能调用

  • 动态多态满足条件:

    • 有继承关系
    • 子类重写父类的虚函数(函数重载)
  • 动态多态使用条件:父类指针或引用指向子类对象

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值