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