一、什么是靜態(tài)成員?
由關鍵字static修飾類體中成員,稱為類靜態(tài)成員(static class member)。類的靜態(tài)成員為其所有對象共享,不管有多少對象,靜態(tài)成員只有一份存于公共內(nèi)存中。靜態(tài)數(shù)據(jù)成員被當作該類類型的全局對象。
二、靜態(tài)屬性
在類設計中,用關鍵字static修飾的數(shù)據(jù)成員為靜態(tài)數(shù)據(jù)成員。由該類型實例化的所有對象,共享系統(tǒng)為靜態(tài)成員分配的一個存儲空間,而這個存儲空間是程序執(zhí)行main函數(shù)之前分配的,在實例化對象時不再為靜態(tài)成員分配空間(靜態(tài)成員數(shù)據(jù)不在對象空間中)。
1、設計靜態(tài)數(shù)據(jù)成員目的是信息共享;
示例:
class Circle
{
private:
double pi; //
double radius; // 半徑
public:
Circle(double r = 0.0):pi(3.14),radius(r) {}
~Circle() {}
void area() const
{
return pi * radius * radius;
}
};
int main()
{
Circle cir(12.23);
cir.area();
size_t sz = sizeof(cir);
return 0;
}
?全局變量:
double pi = 3.14;
class Circle
{
private:
double radius; // 半徑
public:
Circle(double r = 0.0):pi(3.14),radius(r) {}
~Circle() {}
void area() const
{
return pi * radius * radius;
}
};
類的靜態(tài)數(shù)據(jù)成員:
class Circle
{
private:
//靜態(tài)成員的聲明,注意私有
static double pi;
private:
double radius;
public:
Circle(double r = 0.0):pi(3.14),radius(r) {} //error
Circle(double r = 0.0):radius(r) {} // ok;
Circle(double r = 0.0):radius(r)
{
pi = 3.14; // ok; 但是沒有必要
}
};
//靜態(tài)成員的定義
double Circle::pi = 3.14;
總結(jié):
同全局變量相比,使用靜態(tài)數(shù)據(jù)成員有兩個優(yōu)勢:
1、靜態(tài)數(shù)據(jù)成員沒有進入程序的全局名字空間,因此不存在與程序中其他全局名字沖突的可能性。
2、可以實現(xiàn)信息隱藏,靜態(tài)成員可以是private成員,而全局變量不能。?
2、靜態(tài)數(shù)據(jù)是該類所有對象所共有的,可提供同一類型的所有對象之間,信息共享或信息交換的一種方式。
靜態(tài)數(shù)據(jù)成員屬于整個類型,使用時可用以下格式:
類名::靜態(tài)數(shù)據(jù)成員名 或 對象.靜態(tài)數(shù)據(jù)成員名(前提是可訪問符為public)
示例:
用靜態(tài)數(shù)據(jù)成員記錄由同一類建立的對象的數(shù)量。
定義學生類,統(tǒng)計學生的信息:
- 通過定義一個全局變量統(tǒng)計當前學生總數(shù),全局變量可以實現(xiàn)對象的共享,但是沒有權限的限制,導致其他的函數(shù)或者對象可以無限制修改,則會出現(xiàn)問題(不安全);
- 使用static,利用普通成員變量進行統(tǒng)計,普通成員變量是本類某個對象獨有的,類作用域,不能實現(xiàn)共享,外界修改不了(比較安全)。
int m_count = 0;//1、全局變量
//全局變量可以實現(xiàn)對象的共享,但是沒有權限的限制,導致其他的函數(shù)或者對象可以無限制修改,則會出現(xiàn)問題(不安全)
class Student
{
public:
Student(int num = 0, const char* name = "", char sex = 'm'):m_num(num), m_sex(sex)
{
m_name = new char[strlen(name) + 1];
strcpy_s(m_name, strlen(name) + 1, name);
m_count++;
}
~Student()
{
if (m_name != NULL)
{
delete[]m_name;
m_name = NULL;
}
}
void Print(){
cout << "總數(shù)" << m_count << endl;
}
private:
int m_num;
char* m_name;
char m_sex;
static int m_count;//2、普通成員變量是本類某個對象獨有的,類作用域,不能實現(xiàn)共享,外界修改不了(比較安全)
};
int Student::m_count;
void main()
{
Student s(1001, "張三", 'm');
Student s1(1003, "張三", 'w');
Student s2(2005, "張三", 'm');
s.Print();
s1.Print();
s2.Print();
}
3、在類的成員函數(shù)中使用靜態(tài)數(shù)據(jù)成員,靜態(tài)數(shù)據(jù)成員之前沒有this
class Cat // 貓
{
private:
static int num;
private:
std::string _owner; //貓主
std::string _name; //貓名
public:
Cat(const string &owner,
const string &name):_owner(owner),_name(name)
{
num+=1;
cout<<"create Cat num: "<< num<<endl;
}
~Cat()
{
num-=1;
cout<<"Destroy Cat num: "<<num<<endl;
}
void print() const
{
cout<<"Owner: "<<_owner<<" Name: "<<name<<endl;
num+=1; // not this;
}
};
4、若類中含有靜態(tài)成員,則該成員不在能本類中開辟空間,靜態(tài)數(shù)據(jù)成員不占類的大小,不能在構造函數(shù)中初始化。
class A
{
public:
//A():m_a(1),m_b(2),m_c(3){}//m_c不能在構造函數(shù)中初始化
A() :m_a(1), m_b(2)
{
//m_c = 3;//賦值, 沒有給m_c開辟空間
m_c++;
}
void Print()
{
cout << m_c << endl;
}
private:
int m_a;//4
char m_b;//1 1->4
static int m_c;//m_c沒有在A類開辟空間
//引用性聲明,僅用于聲明
};
int A::m_c = 0;//定義性聲明 開辟空間
void main()
{
cout << sizeof(A) << endl;
A a;
a.Print();
A b;
b.Print();
}
5、靜態(tài)屬性的類型是int,short,char,并且是const,可以在類中直接初始化
class Bar
{
private:
static const int nameSize = 20; // ok;
static const char name[nameSize]="xiao cheng bar"; // error;
};
?6、靜態(tài)數(shù)據(jù)成員的類型可以是其所屬類,而非static數(shù)據(jù)成員只能被聲明為該類的指針
class Bar
{
private:
std::string _name;
private:
static Bar sm_bar; // ok;
private:
Bar m_bar; // error;
Bar *pb; // ok;
};
總結(jié):
1、設計靜態(tài)數(shù)據(jù)成員目的是信息共享和信息交流
2、類的靜態(tài)數(shù)據(jù)成員為所有類對象所共享,不屬于某個具體的實例
3、類的靜態(tài)數(shù)據(jù)成員必須在類外定義,定義時不添加static關鍵字,不能在構造函數(shù)的初始化列表中創(chuàng)建
4、類的靜態(tài)數(shù)據(jù)成員類型是int,short,char,long long,并且是const,可以在類中直接初始化,也可以在類外初始化
5、在類的成員函數(shù)中使用靜態(tài)數(shù)據(jù)成員,靜態(tài)數(shù)據(jù)成員之前沒有this
6、當類的靜態(tài)數(shù)據(jù)成員為公有時,可以在外部函數(shù)使用:類名::靜態(tài)數(shù)據(jù)成員名 或 對象.靜態(tài)數(shù)據(jù)成員名,可以在類體中定義自身的靜態(tài)類型對象
三、靜態(tài)方法?
函數(shù)成員說明為靜態(tài),將與該類的不同對象無關。靜態(tài)函數(shù)成員的調(diào)用,在對象之外可以采用下面的方式:
類名::函數(shù)名 或 對象名.函數(shù)名
與靜態(tài)數(shù)據(jù)成員相反,為使用方便,靜態(tài)函數(shù)成員多為公有。
class Object
{
private:
static int num;
private:
int value;
public:
Object(int val = 0):value(val),num(val) {}// error;靜態(tài)屬性只能在類外初始化
Object(int val):value(val)
{
num = 1; // 不是初始化,是賦值
}
void print()
{
cout<<"value: "<<value<<" num: "<<num<<endl;
}
static void show() // 靜態(tài)函數(shù) not this
{
cout<<"value: "<<value<<" num: "<<num<<endl;
}
static void fun(Object &obj) // const // 不能定義為常方法。
{
cout<<obj.value<<" "<<num<<endl;
}
};
int Object::num = 0;
?靜態(tài)成員函數(shù)沒有this指針,因此在靜態(tài)成員函數(shù)顯式地使用this指針都將導致編譯時刻錯誤。試圖訪問隱式使用this指針所指向的非靜態(tài)數(shù)據(jù)成員也會導致編譯時刻錯誤。
class Student
{
public:
Student(int num = 0, const char* name = "", char sex = 'm') :m_num(num), m_sex(sex)
//m_count(0),m_num(num),m_sex(sex)
{
m_name = new char[strlen(name) + 1];
strcpy_s(m_name, strlen(name) + 1, name);
m_count++;
}
~Student()
{
if (m_name != NULL)
{
delete[]m_name;
m_name = NULL;
}
}
void Print() {
cout << "總數(shù)" << m_count << endl;
}
//在static函數(shù)中,沒有this指針,所以不能直接輸出非靜態(tài)數(shù)據(jù)成員
static void Show(Student &s )
{
cout << "Show" << endl;
cout << s.m_num << s.m_name << s.m_sex << m_count << endl;
}
private:
int m_num;
char* m_name;
char m_sex;
static int m_count;
//const int m_j;//成員初始化列表
//const static int m_i = 20;
};
int Student::m_count;
void main()
{
Student s(1001, "張三", 'm');
Student s1(1003, "張三", 'w');
Student s2(2005, "張三", 'm');
s.Print();
s1.Print();
s2.Print();
s.Show(s);//沒有this指針來接收,不管是用哪個對象來調(diào)用static,本質(zhì)使用當前對象的類型Student來調(diào)用
Student::Show(s2);//right,不用特別去聲明成員調(diào)用此函數(shù)
//Student::Print();//error,非靜態(tài)只能用對象來調(diào)用,非static中,有this指針,必須通過對象來調(diào)用
}
?總結(jié):
一個常規(guī)的成員函數(shù)聲明描述了三件在邏輯上相互不同的事情:
- 該函數(shù)能訪問類聲明的私用部分。
- 該函數(shù)位于類的作用域之中。
- 該函數(shù)必須由一個對象去激活(有一個this指針)。
將一個函數(shù)聲明為友元可以使它只具有第一種性質(zhì)。文章來源:http://www.zghlxwxcb.cn/news/detail-408552.html
將一個函數(shù)聲明為static可以使它只具有第一種和第二種性質(zhì)。文章來源地址http://www.zghlxwxcb.cn/news/detail-408552.html
到了這里,關于C++靜態(tài)成員(static)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!