问题一:指针与引用的区别
疑问 为什么引用的本质是指针常量,但是对它求sizeof却是变量所占内存空间的大小那??????????
1.引用是给变量起了个别名,而指针本身是个变量,储存变量的地址
2.引用必须初始化,但指针变量可以不初始化,为野指针
3.引用不能初始化为空,但是指针可以初始化为空,为空指针
4.引用的本质是指针常量,所以不能改变引用关系,但是指针可以改变指向
5.用引用接收传递过来的参数可以不判空,但是指针必须判空
6.没有多级的引用,俩个&&是右值引用不是多级引用,但是又多级指针
7.引用所占空间的大小就是它起别名变量的大小,但是指针所占空间的大小不是4字节就是8字节,看编译环境
8.引用自增后相当于变量的自增,但是指针自增后相当于p的指向向后偏移了它存储类型所占空间大小那么长
问题二:c++中static的作用
1.C/C++共有的
1.静态全局变量可以使作用域缩小变为同一个文件下
2.静态局部变量可以使声明周期变长,不会随着函数的结束而结束
3.静态全局函数也是可以使作用域缩小变为同一个文件下
2.C++独有的
静态成员变量
1.存储再静态区,不占对象内存
2.属于类不属于对象,所有对象共享一份静态成员变量
3.类内声明,类外初始化
4.可以通过类名或者对象名进行调用
5.分配内存在编译阶段,主函数之前
静态成员函数
1.存储在代码段,不占对象内存
2.属于类不属于对象
3.没有this指针,所以不能访问静态成员变量,也不能调用静态成员函数
4.能访问的只有,传递过来的形参,静态成员变量和函数,以及全局变量和全局函数
5.俩种访问方式对象名或者是类名
静态函数的好处和静态全局变量一样,都是别的文件不可以访问,在不同文件下定义相同的名字不会发生冲突
深层:
1.为什么静态成员函数不能申明为const?
使用const函数的目的是不想让在常函数内部修改成员变量的值,但是我静态成员函数已经没有this指针了,肯定不会改变非静态成员变量的值了,也就不用担心这个问题
2.为什么静态成员变量要类内定义,类外初始化那?
因为静态成员变量属于类不属于对象,所以如果在类内初始化的话,岂不是每一个对象都拥有了一份静态成员变量,这不就矛盾了吗,所以静态成员变量必须类内声明,类外初始化
3.static关键字为什么只能出现在类内部的声明语句中,而不能重复出现在类外的定义中?
类出现的目的就是多文件之间的交互,你把这个类static了,作用域变成本文件了,还咋交互了!
4.为什么常量静态成员数据的初始化可以放在类内(注意:只有静态常量整型数据成员才可以在类中初始化
疑问,不懂!!!!!
5.为什么静态成员函数只能访问静态成员变量
因为静态成员函数没有this指针,无法访问非静态成员,所以只能访问静态成员
6.静态成员函数与非静态成员函数的区别
我认为只要的区别是this指针
7.为什么要用得静态成员变量和静态成员函数
因为静态成员函数和静态成员变量都是属于类不属于对象,多个对象共享一份,可以共享!!!
本文章参考c++中static的作用_static在c++中的作用-CSDN博客
用自己的话回答了该作者在文件提出的问题!!
问题三:智能指针
为什么要由智能指针?
因为对象有的在栈区有的在堆区,栈区的对象大括号结束就可以被销毁了,但是堆区的必须手动释放才能销毁,容易忘,所以才有智能指针这东西
#include <iostream>
using namespace std;
class Test {
public:
Test() { cout << "Test的构造函数..." << endl; }
~Test() { cout << "Test的析构函数..." << endl; }
int getDebug() { return this->debug; }
private:
int debug = 20;
};
void text01() {
Test* test = new Test;
//析构函数的调用时机是:对象被销毁的时候,析构会释放对象里成员变量指向的堆区空间
//但是此时对象在栈区,如果不手动释放的话不会销毁,所以需要手动释放
}
//cout<<只有构造函数
int main() {
text01();
return 0;
}
1.auto_ptr智能指针
2.unique_ptr智能指针
3.shared_ptr智能指针
4.weak_ptr智能指针
#include <iostream>
using namespace std;
class Test {
public:
Test() { cout << "Test的构造函数..." << endl; }
~Test() { cout << "Test的析构函数..." << endl; }
int getDebug() { return this->debug; }
private:
int debug;
};
//***********auto_ptr
void text01() {
auto_ptr<Test> s(new Test);//智能指针是一个类的对象,它能像指针一样使用是因为重载了运算符
//析构函数的调用时机是:对象被销毁的时候,析构会释放对象里成员变量指向的堆区空间
//但是此时对象在栈区,如果不手动释放的话不会销毁,所以需要手动释放
cout << s->getDebug() << endl;
cout << (*s).getDebug() << endl;
//智能指针可以像指针一样使用,因为智能指针重载了->和.运算符
cout << s.get() << endl;
//s下的get方法,获取智能指针的地址
cout << s.release() << endl;
//s下的release方法,取消托管,所以下面不会调用析构函数了
}
//cout<<构造函数<<析构函数
void text02() {
auto_ptr<Test> s1(new Test);
auto_ptr<Test> s2(new Test);
s1 = s2;
//只要智能指针被赋值给另外一个同类型的智能指针的话,它托管的堆区对象就会被销毁,自己的值也会被赋值为空
cout <<"s1:" << s1.get() << endl;
cout <<"s2:" << s2.get() << endl;
}
void text03() {
/*auto_ptr<int[] > s1(new int[5])*/;//不能托管对象数组
}
//auto_ptr智能指针被C++11抛弃的原因
/*
* 1.赋值或者拷贝之后所有权会变化
* 2.在STL容器中使用auto_ptr存在着重大风险,因为容器内的元素必须支持可复制和可赋值??????没学过
* 3.不支持对象数组的内存管理
*/
//***********unique_ptr
void text04() {
unique_ptr<Test> s1(new Test);
unique_ptr<Test> s2(new Test);
/*s1 = s2*/;//因为禁止左值赋值,所以不能俩个指针指向同一个资源
//容器内保存指针是安全的
/*unique_ptr<Test> s3(s1);*///禁止左值拷贝构造
s1 = std::move(s2);//把s2由左值转为右值,允许右值赋值
unique_ptr<Test> s4(std::move(s1));
unique_ptr<int[]> s5(new int[5]);//支持托管对象数组
}
void text06(){
shared_ptr<Test> s1(new Test);
shared_ptr<Test> s2(s1);
shared_ptr<int[]> s3(new int[5]);
cout << "s1:" << s1.use_count() << "s2:" << s2.use_count() << "s3:" << s3.use_count() << endl;
//引用计数use_count()函数
shared_ptr<Test> s4 = make_shared<Test>();
}
//shared_ptr要避免交叉持有对方管理对象
int main() {
text06();
return 0;
}