1.static成员
a)⽤static修饰的成员变量,称之为静态成员变量,静态成员变量⼀定要在类外进行初始化。
b)静态成员变量为所有类对象所共享,不属于某个具体的对象,不存在对象中,存放在静态区。
例如:
cpp
class A
{
public:
static int _scont;
};
int A::_scont = 0;
int main()
{
cout << sizeof(A) << endl;
cout << A::_scont << endl;
A a1;
A a2;
cout << a1._scont << endl;
cout << a2._scont << endl;
return 0;
}
结果:
这里sizeof(A)=1(这里的是1而不是0,是因为表示占位,这里有一个A类,具体可以看看小编前面的文章"类,实例化,this指针"中有详细讲解)可以看出,static修饰的成员变量,并没有放在类中,而是放在静态区。_scont成员前提是在public中时,可以通过A类直接访问,也可以通过,实例化的对象进行访问。
c)⽤static修饰的成员函数,称之为静态成员函数,静态成员函数没有this指针。
cpp
class A
{
public:
A()
{
++_scount;
}
A(const A& t)
{
++_scount;
}
~A()
{
--_scount;
}
static int GetACount()
{
++_a1;
return _scount;
}
private:
// 类里面声明
static int _scount;
int _a1 = 1;
int _a2 = 1;
};
这里正是因为没有this指针无法访问非静态变量。
e)非静态的成员函数,可以访问任意的静态成员变量和静态成员函数。
f)突破类域就可以访问静态成员,可以通过类名::静态成员 或者对象.静态成员来访问静态成员变量和静态成员函数。
g)静态成员也是类的成员,受public、protected、private访问限定符的限制。
h)静态成员变量不能在声明位置给缺省值初始化,因为缺省值是个构造函数初始化列表的,静态成员变量不属于某个对象,不⾛构造函数初始化列表。
例如:
所以这里不能给缺省值,因为这种方式是通过初始化列表初始化,而这种静态变量不走初始化列表初始化,所以就要在类外初始化。
2.匿名对象
a)⽤类型(实参)定义出来的对象叫做匿名对象,相⽐之前定义的类型对象名(实参)定义出来的叫有名对象。
b)匿名对象⽣命周期只在当前⼀⾏,⼀般临时定义⼀个对象当前⽤⼀下即可,就可以定义匿名对象。
例如:
cpp
class A
{
public:
A(int a = 0)
:_a(a)
{
cout << "A(int a)" << endl;
}
~A()
{
cout << "~A()" << endl;
}
private:
int _a;
};
int main()
{
A();
A(1);
return 0;
}
A aa1();不能这么定义对象,因为编译器⽆法识别下⾯是⼀个函数声明,还是对象定义,但是可以这么定义匿名对象,匿名对象的特点不用取名字,但是他的⽣命周期只有这⼀⾏,我们可以看到下⼀⾏他就会⾃动调⽤析构函数。
注意:当引用匿名对象时,就可以延长它的生命周期;
例如:
cpp
class A
{
public:
A(int a = 0)
:_a(a)
{
cout << "A(int a)" << endl;
}
~A()
{
cout << "~A()" << endl;
}
private:
int _a;
};
int main()
{
const A& a1 = A(0);
A();
A(1);
return 0;
}
结果:
可以看到a1是在最后才调用析构函数的,延长了A(0)的生命周期。