C++知识点

1 C++ 初级部分需要注意的知识

(1) C++ 程序的分文件编写

步骤:

    1、创建.h后缀的头文件
    2、创建.cpp后缀名的源文件
    3、在头文件写函数声明
    4、载源文件写函数定义

例如:

    交换两个数的程序中
    
    (1) 在swap.h文件中
            #include<iostream>
            using namespace std;
            void swap(int a,int b);
        
    (2) 在swap.cpp文件中
            #include"swap.h"
            void swap(int a,int b){
            	
            	int temp;
            	temp=a;
            	a=b;
            	b=temp;
            	
            	cout<<a<<endl;
            	cout<<b<<endl;
            }
            
    (3) 测试文件
            #include"xug.h"
            int main(){
            	swap(2,3);
            	return 0;
            }
复制代码

(2) 问:指针也是一种数据类型,那么指针占有多少个字节?

在32位操作系统中,指针占有4个字节
在64位操作系统中,指针占有8个字节

int* char* long*等等,都属于指针类型
复制代码

(3) const修饰符

int const * p; 
    特点:指针的指向可以修改,指针指向的值不可以修改
    
int * const p; 
    特点:指针的指向不可以修改,指针指向的值可以修改
    
int const * const p; 
    特点:指针的指向不可以修改,指针指向的值也不可以修改
复制代码


2 C++ 中级部分需要注意的知识

2-1 new关键字

int * p = new int(10);
delete p;

int * arr = new int[10];
delete[]arr;
复制代码

2-2 引用类型

(1) 引用类型

#include<iostream>
using namespace std;

int main(){
	
	int a=10;
	int &b=a;//b引用a
	cout<<a<<endl; //10
	cout<<b<<endl; //10
	
	//引用后a和b就是一个共同体,即不管a还是b发生变化,则它们一起发生变化
	b=100; 
	cout<<a<<endl; //100
	cout<<b<<endl; //100
	
	return 0;
}

注意:
    1、引用必须初始化。
            即:&b=a 初始化
    2、引用在初始化后,不可以改变。
            即:b只能和a是共同体了。
复制代码

(2) 引用类型做函数的参数

1、普通参数传递
    #include<iostream>
    using namespace std;
    
    void swap(int a,int b){
    	int temp=a;
    	a=b;
    	b=temp;
    } 

    int main(){
    	
    	int a=10;
    	int b=20;
    
    	swap(a,b);//普通传参 
    	cout<<a<<endl;//10
    	cout<<b<<endl;//20
    
    	return 0;	
    } 
    
2、引用类型参数传递
    #include<iostream>
    using namespace std;
    
    void swap(int &a,int &b){
    	int temp=a;
    	a=b;
    	b=temp;
    } 

    int main(){
    	
    	int a=10;
    	int b=20;
    
    	swap(a,b);//引用传参 
    	cout<<a<<endl;//20
    	cout<<b<<endl;//10
    
    	return 0;	
    } 

3、指针类型参数传递      
    #include<iostream>
    using namespace std;
    
    void swap(int *a,int *b){
    	int temp= *a;
    	*a=*b;
    	*b=temp;
    } 
    
    int main(){
    	
    	int a=10;
    	int b=20;
    
    	swap(&a,&b);//指针传参 
    	cout<<a<<endl;//20
    	cout<<b<<endl;//10
    	
    	return 0;	
    } 
    
复制代码

(3) 引用类型做函数的返回值

 1、不要返回局部变量的引用
        #include<iostream>
        using namespace std;
        
        int & test(){
        	int a=10;
        	return a;
        } 
        
        int main(){
        	
        	int	&b=test();
        	cout<<b<<endl;//10
        	cout<<b<<endl;//0
        	
        	return 0;	
        } 
        
    第一次正确,是因为编译器对a的值做了保留
    
    第二次错误,是因为a的内存已经释放
    
2、函数的调用可以作为左值

    #include<iostream>
    using namespace std;
    
    int & test(){
    	static int a=10;//静态变量,在全局区 
    	return a;
    } 
    
    int main(){
    	
    	int	&b=test();
    	cout<<b<<endl;//10
    	cout<<b<<endl;//10
    	
    	test()=100;
    	cout<<b<<endl;//100
    	cout<<b<<endl;//100
    	
    	return 0;	
    } 
    
复制代码

(4) 引用类型的本质

引用的本质在C++内部实现的是一个指针常量。

int * const p; 
特点:指针的指向不可以修改,指针指向的值可以修改
复制代码

(5) 常量引用

用来修饰形参,防止误操作。
复制代码

2-3 函数提高

(1) 函数的默认参数

#include<iostream>
using namespace std;

int fun(int a,int b=20,int c=30){
	return a+b+c;
}

int main(){
	
	cout<<fun(10)<<endl;//60
	cout<<fun(10,60)<<endl;//100
		
	return 0;	
}  

注意:
    1、语法:返回值类型 函数名(数据类型 形参=默认值)。
    
    2、如果我们自己传入数据,就用自己的数据,如果没有,那么用默认值。
    
    3、如果某个位置已经有了默认参数,那么从这个位置往后,从左到右必须都有默认值。
    
    4、如果函数声明和实现不能同时设置默认参数。
    
           目的:防止函数声明和实现的默认参数不同,造成二义性。
    
复制代码

(2) 函数占位符参数

C++中函数的形式参数列表里可以有占位参数,用来做占位,调用函数时 必须 填补该位置。

语法:返回值类型 函数名(数据类型)。

函数占位默认参数:返回值类型 函数名(数据类型=默认值)。
复制代码

3 类和对象

(1) 构造函数的分类和调用

常用分法:默认构造函数、有参构造函数、拷贝构造函数 

    class Person{
    public:
    	Person(){
    		cout<<"Person无参构造函数"<<endl; 
    	}
    	Person(int a){
    		age=a;
    		cout<<"Person有参构造函数"<<endl; 
    	}
    	Person(const Person &p){
    		age=p.age;
    		cout<<"Person拷贝参构造函数"<<endl; 
    	}
    	~Person(){
    		cout<<"Person析构函数"<<endl; 
    	}
    	int age; 
    };
    
调用:

	1、括号法
    	Person person1;//默认构造函数
    	Person person2(10);//有参构造函数
    	Person person3(person2);//拷贝构造函数 
    	
    	注意:
            在调用默认构造函数时,不要加括号
            不能写成Person person1(),这样写编译器会把他当成函数声明; 
            
    	
    2、显示法
    	Person person1 = Person();//默认构造函数
    	Person person2 = Person(10);//有参构造函数
    	Person person3 = Person(person2);//拷贝构造函数 
    	
    	注意:
    	    Person(10) 匿名对象 特点:当前执行结束后,系统会立即回收掉匿名类
            不要利用拷贝构造函数 初始化匿名对象 编译会认为 Person(person3) = Person person3; 
            Person(person3); //错误语法 
            
   3、隐式转换法
    	Person person4 = 10;//相当于 Person person4 = Person(10); 有参构造
    	Person person5 = person4; //相当于拷贝构造
    	
复制代码

(2) 拷贝构造函数的调用的时机

1、通过使用另一个已经创建好的同类型的对象来初始化新创建的对象。

2、复制对象把它作为参数传递给函数。

3、复制对象,并从函数返回这个对象。
复制代码

(3) 构造函数的调用规则

默认情况下,C++编译器至少会给一个类添加3个函数

    1、默认构造函数,无参、函数体为空
    
    2、默认析构函数,无参、函数体为空
    
    3、默认拷贝构造函数,对属性进行值拷贝

注意:
    
    如果用户定义有参构造函数,C++不会在提供默认构造函数,但是会提供默认拷贝构造函数。
    
    如果用户定义拷贝构造函数,C++不会在提供其他构造函数。
复制代码

(4) 深拷贝与浅拷贝

浅拷贝:简单的赋值操作

深拷贝:在堆区重新申请空间,进行拷贝工作。
    要自己写拷贝函数,
    (并不一定适用)在C++中,指针的赋值一般用new
复制代码

(5) 初始化列表

语法: 构造函数():属性1(值1),属性2(值2){}
复制代码

(6) 组合注意事项

当其他类作为本类的成员时,构造时先构造类对象,在构造本身。
复制代码

(7) 静态成员变量

1、所有对象都共享同一份数据。
2、编译阶段就分配内存。(Java是在加载时分配内存)
3、类内声明,类外初始化。(Java是在类内定义和声明,定义时初始化不都可以)

使用:

    通过对象访问 对象名.静态成员变量(public)
    通过类名访问 类名::静态成员变量(public)

静态成员函数..............
复制代码

(8) const修饰成员函数

常函数:
    a.成员函数后加const后我们称为这个函数为常函数
    b.常函数内不可以修饰成员属性
    c.成员属性声明时加关键字mutable后,在常函数中依然可以修改
    
    格式:返回值类型 函数名() const{}
    
常对象:
    a.声明对象前加const该对象为常对象
    b.常对象只能调用常函数
    
const:只读
复制代码

(9) 友元函数

类的友元函数是定义在类外部,但有权访问类的所有私有(private)成员和保护(protected)成员。

尽管友元函数的原型有在类的定义中出现过,但是友元函数并不是成员函数。

友元可以是一个函数,该函数被称为友元函数;

友元也可以是一个类,该类被称为友元类,在这种情况下,整个类及其所有成员都是友元。


友元的三种实现:
    1、全局函数做友元。
    
        //全局函数,Person类
        void test1(Person &p){
    	    cout<<p.age;
         }
                
        在Person类的最前面声明为:friend void test1(Person &p); 不加修饰符
        
    2、类做友元。
    
        有两个类Person和Student类,如果想让Student访问Person类中的私有成员和保护成员,则需要在Person类的最前面加:
            friend class Stduent;不加修饰符
    
    
    3、成员函数做友元。
        有两个类Person和Student类,如果想要Student类中的某个成员函数void A(),访问Person类中的私有成员和保护成员,则需要在Person类的最前面加声明:
            friend void Student::A();不加修饰符
        
复制代码

(10) 运算符重载

a.对于内置的数据类型,编译器知道如何进行运算。

b.运算符重载的两种方式:成员运算符函数和友元运算符函数

c.运算符重载的格式:

    成员运算符函数
        类型 类名::operator 重载的运算符(参数列表){
            函数体;
        }
    
    友元运算符函数
        friend 类型 类名::operator 重载的运算符(参数列表){
            函数体;
        }
        
复制代码

(11) 运算符重载的注意事项

a.在c++中,除了5个运算符( .  *  ::   Sizeof  ?: )不能重载之外,其余全部都可以重载。

b.运算符重载可以改变运算符原来的行为,但是重载之后运算符的优先性、结合性和操作数个数都不会改变,只能重载已有的这些运算符。

c.运算符重载后的功能与原有的功能相似,运算符重载函数的参数至少有一个必须是自定义类型。

d.在重载运算符()、[ ]、-> 或者 = 时,运算符重载函数必须声明一个为类的一个成员,对于其他运算符,运算符重载函数可以是成员函数或者是友元函数。
复制代码
① 加号运算符重载

3 C++ 中的高级部分

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享