(构造函数的补充2)类型转换与临时变量(新对象)的生成与explicit关键字
- 如果说一个构造函数是单个参数,或者说有多个参数但是第一个参数没有默认值,而其余均有默认值,这时候就特别需要注意类型转换的问题。
- 首先必须得知道的一点就是说一旦有类型转换发生,那么就必然会有临时变量的生成,然后因为临时变量是具有常性的,所以这边又会牵扯到之前的一个引用的权限问题,这别不做过多延伸,之前我博客写过。
- 然后比如说用一个类a的实例化对象去等于另外一个不同类型的变量(比方说是内置类型),那么首先就是会创建一个临时变量(并且这个临时变量的类型的话就是a,所以说开辟出来也就是a的大小),然后这时候就相当于类的实例化对象被创建了一个出来,根据一语双关的知识的话,就可以立马得知与此同时构造函数也得以进行同步调用,并且这个构造函数的参数索取的话,就会用等号右边的那个变量
- 然后接下来这个刚刚创建的临时变量(也可以称之为类型a的一个无名对象)再会给等号左边的那个实例化对象进行一个赋值操作,流程的话大概就是这样子。
- 上述代码可读性不是很好,用explicit修饰构造函数,将会禁止构造函数的隐式转换
类中的静态成员有关知识介绍
- 用static修饰类的实例化对象,那么就说明此刻那个对象是在内存的静态区里面,就不是在当前的函数栈帧里面,就说明两点:第一的话就是说不会随着函数栈帧的销毁而发生消灭;第2点就是说他也不会被重复创建,因为就已经在静态区里面了,他也重复创建不了
- 就是说在类当中不仅可以定义普通的那些成员变量,你也可以去定义那些静态成员变量。这两者的区别就在于对于那些普通的成员变量而言,它是属于每一个类的实例化对象;然后对于那些静态成员变量而言,它是属于类,相当于是属于每一个类的实例化对象共享;一个是存储在类的实例化对象的内存空间当中,而那个静态的成员变量,它是存储在内存的静态区当中,所以说他的生命周期是全局的。
- 然后他静态成员变量声明的时候当然很容易,但是定义的时候就会发生很多麻烦,很明显的一点就是说不可能在类当中去定义,所以说对于类的静态成员变量是在全局位置,也就是在类的外面去定义的。
int A::_scount = 0;
- 单纯在一个类当中的话,普通成员函数当中是可以去调用静态成员函数的,但是在静态成员函数当中是不能够去调用普通成员函数,最主要的原因在于他是没有this指针的,而如果说你在静态成员函数当中去放一个普通成员函数,那么那个普通成员函数this指针这个空白由谁来填?
静态成员变量的总结
- 不会出现在构造函数
- 没有缺省值
- 必须在类外面初始化:
int A::_scount = 0;
- 在类中的可以自由被使用
- 在类外面要直接访问,首先必须是public,然后就这样:
Stu::_scount
- 如果是private/protect,只能去实现一个成员函数获取该静态成员变量
静态成员函数的总结
- 没有this 指针, 所以在静态成员函数中访问类的成员变量与调用其他成员函数
- 类外面调用的话,首先必须是public,然后就是直接这样调用:(不是必须要 实例化对象 . 成员函数 这样子)
类名:: func();
静态成员变量与函数的应用1
luck
代码:
class Sum
{
public:
Sum()
{
s+=i;
i++;
}
int static GetSum()
{
return s;
}
private:
static int i;
static int s;
};
int Sum::i =1;
int Sum::s =0;
class Solution
{
public:
int Sum_Solution(int n)
{
Sum arr[n];
return Sum::GetSum();
}
};
静态成员变量与函数的应用2
- 设计一个类,在类外面只能在栈上创建对象,设计一个类,在类外面只能在堆上创建对象
class A
{
public:
static A GetStackObj()
{
A aa;
return aa;
}
static A* GetHeapObj()
{
return new A;
}
private:
A()
{}
};
int main()
{
A::GetStackObj();
A::GetHeapObj();
return 0;
}