「这是我参与2022首次更文挑战的第26天,活动详情查看:2022首次更文挑战」
💦 概念
❓ 写一个程序,计算程序构造了多少个对象 (构造+拷贝构造) ❔
int countC = 0;
int countCC = 0;
class A
{
public:
A()
{
++countC;
}
A(const A& a)
{
++countCC;
}
};
A f(A a)
{
A ret(a);
return ret;
}
int main()
{
A a1 = f(A());
A a2;
A a3;
a3 = f(a2);
cout << countC << endl;
cout << countCC << endl;
return 0;
}
📝说明
这样虽然能计算出结果,但是有一个问题,countC 和 countCC 是可以随便改的,这样就很不好。
优化 ❓
class A
{
public:
A()
{
++_count;
}
A(const A& a)
{
++_count;
}
int GetCount()
{
return _count;
}
static int GetCount()
{
return _count;
}
private:
int _a;
static int _count;
};
//定义初始化
int A::_count = 0;
A f(A a)
{
A ret(a);
return ret;
}
int main()
{
A a1 = f(A());
A a2;
A a3;
a3 = f(a2);
cout << sizeof(A) << endl;
//这里就体现了static成员属于整个类,也属于每个定义出来的对象共享,但限制于公有
/*cout << A::_count << endl;
cout << a1._count << endl;
cout << a2._count << endl;*/
/*A ret;
cout << ret.GetCount() - 1 << endl;*/
/*cout << A().GetCount() - 1 << endl;*/
cout << A::GetCount() << endl;
return 0;
}
📝说明
int _a; 存在定义出的对象中,属于对象。
static int _count; 存在静态区,属于整个类,也属于每个定义出来的对象共享。跟全局变量比较,它受类域和访问限定符限制,更好的体现封装,别人不能轻易修改。
static成员 ❓
对于非 static 成员它们的定义是在初始化列表中,但在 C++ 中,static 静态成员变量是不能在类的内部定义初始化的,这里的内部只是声明。注意这里虽然是私有成员,但是对于 static 成员它支持在外部进行定义,且不需要加上 static,sizeof 在计算的时候并不会计算 static 成员的大小。
_count是私有,怎么访问 ❓
定义一个公有函数 GetCount 函数,返回 _count:
调用,
1、最后实例化对象后调用 GetCount 函数并减 1
2、直接匿名对象并减 1
3、将 GetCount 函数定义成静态成员函数并使用类域调用
💦 特性
1️⃣ 静态成员变量为所有类对象所共享,不属于某个具体的实例。
2️⃣ 静态成员变量必须在类外定义,定义时不添加 static 关键字。
3️⃣ 类静态成员即可用类名::静态成员或者对象.静态成员来访问。
4️⃣ 静态成员函数没有隐藏的 this 指针,不能访问任何非静态成员。
5️⃣ 静态成员和类的普通成员一样,也有 public、protected、private 3 种访问级别,也可以具有返 回值。
【面试题1】
static 的作用 C 语言 | C++ ❓
C 语言:
1、 static 修饰局部变量,改变了局部变量的生命周期 (本质上是改变了变量的存储类型),局部变量由栈区转向静态区,生命周期同全局变量一样
2、 static 修饰全局变量,使得这个全局变量只能在自己所在的文件内部使用,而普通的全局变量却是整个工程都可以使用
❓ 为什么全局变量能在其它文件内部使用 ❔
因为全局变量具有外部链接属性;但是被 static 修饰后,就变成了内部链接属性,其它源文件不能链接到这个静态全局变量了
3、static 修饰函数,使得函数只能在自己所在的文件内部使用,本质上 static 是将函数的外部链接属性变成了内部链接属性 (同 static 修饰全局变量)
C++:
1、修饰成员变量和成员函数,成员变量属于整个类,所有对象共享,成员函数没有 this 指针。
【面试题2】
静态成员函数可以调用非静态成员函数吗 ❓
不能,因为静态成员函数没有 this 指针。
非静态成员函数可以调用静态成员函数吗 ❓
可以,因为非静态成员函数有 this 指针。