常量指针和指针常量
常量指针是不能修改指向地址数据的指针,指针常量是不能改变指向的指针。
引用:一个已经声明的变量别名,相当于指针常量(不能改变指向的指针)
- 在声明时必须初始化 ,初始化以后不能被改变
- 不能有null引用,必须确保是一块合法的存储单元
- 可以建立对数组的引用
定义方法
int a = 10;
int& num = a;
a = 20;
cout<<num<<","<<a<<endl;
// 用引用交换两个变量的值
void swap(int& num1, int& num2) {
int temp = num1;
num1 = num2;
num2 = temp;
}
常量引用 相当于常量指针常量
适用于 方法里面要使用一个变量,但是, 不想这个变量的值不小心被修改
面向对象编程
class Person{
public :
int age;
Person() {}
Person(int age) {
this->age = age;
}
};
int main()
{
// 显示调用
Person p1 = Person();
Person p2 = Person(18);
// 缩写
Person p1;// 不能写括号 写括号时会被认为在定义函数
Person p2(18);
// 隐式调用
Person p3 = {};
Person p4 = {20};// 大括号里面只有一个参数时可以省略大括号
return 0;
}
this 关键字 相当于 指针常量
explicit 修饰构造函数,杜绝隐式函数
class Person{
public :
int age = 30;
Person() {}
explicit Person(int age) {
this->age = age;
}
string toString() {
return " age = " + age;
}
};
int main()
{
Person p1 = {18};//报错 因为上面构造函数上面有explicit关键字 表示该构造函数不能被隐式调用
cout<<p1.toString()<<endl;
return 0;
}
对象的初始化赋值
// 构造函数的初始化赋值
// 书写方式
class Person{
public :
int age;
string name;
Person(): name("小明"),age(18){}// 初始化 对象的name是小明 age是18
};
int main()
{
Person p1 = {};
cout<<"age = " << p1.age<< " name = "<<p1.name<<endl;// 打印 age = 18 name = 小明
return 0;
}
拷贝函数
class Person{
public :
int age;
string name;
Person(string name, int age) {
this->age = age;
this->name = name;
}
// 手写拷贝函数 这里不写 系统会自动为我们创建
Person(const Person& p) {
name = p.name;
age = p.age;
}
};
int main()
{
Person p1 = {"小明", 18};
Person p2 = p1;
cout<<"p2.name = "<<p2.name<<" p2.age = "<<p2.age<<endl;
cout<<&p1<<" "<<&p2<<endl;// 0x921d7ffd90 0x921d7ffd60 打印地址不同,说明两个对象不是同一对象
// 原理 自动调用拷贝函数
return 0;
}
析构函数
对象生命周期的终点,一般在这个函数里进行资源释放
class Person{
public :
int *p;
// 析构函数
~Person() {
cout<<"对象被释放"<<endl;
// 释放成员属性的内存
if (p != nullptr) {
delete p;
}
}
};
int main()
{
Person* p1 = new Person();// 被创建在堆区 需要程序员手动释放内存
p1->p = new int(10);
int* t = p1->p;
delete p1;// 释放怕内存
cout<<*t<<endl;//打印10 说明该对象的p成员变量占用的内存没有被释放
return 0;
}