static
static成员独立于类对象存在,也就是说它不属于对象的成员,它能被全体对象所共享。 统计·类类型对象创建的个数,用static成员来实现。 非static成员属于类对象,每个对象都有一份拷贝。 static成员函数没有this指针,他不能访问非static成员,也不能调用非static成员函数。
代码语言:javascript复制静态成员变量在定义性说明时不用再加static关键字。
#include<iostream>
using namespace std;
class CBOOK
{
public:
CBOOK(int price , int nums)
{
this->price = price;
this->nums = nums;
}
int nums;
int price;
static int x ; //静态成员的引用性说明
};
static int CBOOK::x =100; //静态成员的定义性说明,error,static关键字
int main()
{
cout<<CBOOK::x<<endl;
return 0;
}
错误如下:
代码语言:javascript复制staticnumbers.cpp:28:19: error: ‘static’ may not be used when defining (as opposed to declaring) a static data member [-fpermissive]
static int CBOOK::x =100;
^
代码语言:javascript复制静态成员变量不能多次初始化
#include<iostream>
using namespace std;
class CBOOK
{
public:
CBOOK(int price , int nums)
{
this->price = price;
this->nums = nums;
}
int nums;
int price;
static int x = 102;
};
int CBOOK::x =100; //error,多次初始化
int main()
{
cout<<CBOOK::x<<endl;
return 0;
}
错误如下:
代码语言:javascript复制[bsk@localhost classobject]$ g staticnumbers.cpp
staticnumbers.cpp:25:22: error: ISO C forbids in-class initialization of non-const static member ‘CBOOK::x’
static int x = 102;
^
staticnumbers.cpp:27:13: error: duplicate initialization of ‘CBOOK::x’
int CBOOK::x =100;
^
staticnumbers.cpp:27:16: error: ISO C forbids in-class initialization of non-const static member ‘CBOOK::x’
int CBOOK::x =100;
可以使用类初始化的对象来调用静态成员,但是一般不会这样做,因为会容易理解错误,静态成员是属于整体的而不是类对象。
代码语言:javascript复制#include<iostream>
using namespace std;
class CBOOK
{
public:
CBOOK(){}//重载一下空实现,因为当构造函数有参函数出现后,会自动覆盖编译器提供的空实现,从而再想去调用空实现,就会报错。
CBOOK(int price , int nums)
{
this->price = price;
this->nums = nums;
}
int nums;
int price;
static int x = 102;
};
int CBOOK::x =100; //error,多次初始化
int main()
{
CBOOK c;
cout<<CBOOK::x<<endl;
cout<<c.x<<endl;
return 0;
}
代码语言:javascript复制静态成员函数
#include<iostream>
using namespace std;
class CBOOK
{
public:
CBOOK(){}//重载一下空实现,因为当构造函数有参函数出现后,会自动覆盖编译器提供的空实现,从而再想去调用空实现,就会报错。
CBOOK(int price , int nums)
{
this->price = price;
this->nums = nums;
}
void function() //普通·成员函数
{
cout<<"funcyion"<<endl;
cbookfunction();
}
static void cbookfunction() //静态成员函数
{
cout<<"static cbookfuncyion"<<endl;
}
int nums;
int price;
static int x;
};
int CBOOK::x =100; //error,多次初始化
int main()
{
CBOOK c;
cout<<CBOOK::x<<endl;
cout<<c.x<<endl;
c.function();
return 0;
}
在普通·成员函数中可以调用静态成员函数,但是在静态成员函数中不可以·调用普通成员函数,
会出现下面的错误·:
代码语言:javascript复制[bsk@localhost classobject]$ g staticnumbers.cpp
staticnumbers.cpp: In static member function ‘static void CBOOK::cbookfunction()’:
staticnumbers.cpp:31:22: error: cannot call member function ‘void CBOOK::function()’ without object
function();
代码语言:javascript复制静态成员变量在静态成员函数或者非静态成员函数都可以访问
#include<iostream>
using namespace std;
class CBOOK
{
public:
CBOOK(){}
CBOOK(int price , int nums)
{
this->price = price;
this->nums = nums;
}
void function()
{
cout<<"funcyion"<<endl;
cbookfunction();
cout<<x<<endl;
}
static void cbookfunction()
{
// function();
cout<<"static cbookfuncyion"<<endl;
cout<< x<<endl;
}
int nums;
int price;
static int x ;
};
int CBOOK::x =100;
//int Cbook::price = 410;
int main()
{
CBOOK book(12,123);
CBOOK c;
book.function();
return 0;
}
代码语言:javascript复制在静态成员函数中不可以访问·非静态成员变量·
#include<iostream>
using namespace std;
class CBOOK
{
public:
CBOOK(){}
CBOOK(int price , int nums)
{
this->price = price;
this->nums = nums;
}
void function()
{
cout<<"funcyion"<<endl;
cbookfunction();
cout<<x<<endl;
cout<<nums<<endl;
}
static void cbookfunction()
{
// function();
cout<<"static cbookfuncyion"<<endl;
cout<< x<<endl;
cout<<nums<<endl;//error 不可访问
}
int nums;
int price;
static int x ;
};
int CBOOK::x =100;
//int Cbook::price = 410;
int main()
{
CBOOK book(12,123);
CBOOK c;
book.function();
return 0;
}
static用法总结
01.用于函数内部修饰变量,即函数内的静态变最。这种变量的生存期长于该函数,使得函数具有一定的“状态”。使用静态变量的函数一般是不可重入的,也不是线程安全的,比如strtok(3). 02.用在文件级别(函数体之外),修饰变量或函数,表示该变量或函数只在本文件可见,其他文件看不到也访问不到该变量或函数。专业的说法叫“具有internal inkage”(简言之:不暴露给别的translation unit) 03.C语言的这两种用法很明确,一般也不容易混淆
类的大小
- 类的大小遵循结构体对齐原则
- 类的大小与数据成员有关,与成员函数无关
- 类的大小与静态成员函数无关
- 虚函数对类的大小有影响(多虚表指针)
- 虚继承对类的大小有影响
四种作用域
栈对象
隐含用构造函数(程序中没有显示调用)
堆对象
隐含调用构造函数(程序中没有显示调用)
全局对象、静态全局对象
全局对象的构造 先于main函数 已初始化的全局变量或静态全局对象存储于.data段中。 未初始化的全局变量或静态全局对象存储于:bss段中
静态局部对象
已初始化的静态局部变量存储于.data段中, 未初始化的静态局部变量存储于.bss段中