C++静态成员(static)

这篇具有很好参考价值的文章主要介绍了C++静态成员(static)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、什么是静态成员?

由关键字static修饰类体中成员,称为类静态成员(static class member)。类的静态成员为其所有对象共享,不管有多少对象,静态成员只有一份存于公共内存中。静态数据成员被当作该类类型的全局对象。

二、静态属性

在类设计中,用关键字static修饰的数据成员为静态数据成员。由该类型实例化的所有对象,共享系统为静态成员分配的一个存储空间,而这个存储空间是程序执行main函数之前分配的,在实例化对象时不再为静态成员分配空间(静态成员数据不在对象空间中)。

1、设计静态数据成员目的是信息共享;

示例:

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;
}
};

类的静态数据成员:

class Circle
{
private:
//静态成员的声明,注意私有
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; 但是没有必要
}
};
//静态成员的定义
double Circle::pi = 3.14;

总结:

同全局变量相比,使用静态数据成员有两个优势:

1、静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其他全局名字冲突的可能性。

2、可以实现信息隐藏,静态成员可以是private成员,而全局变量不能。 

2、静态数据是该类所有对象所共有的,可提供同一类型的所有对象之间,信息共享或信息交换的一种方式。

静态数据成员属于整个类型,使用时可用以下格式:

类名::静态数据成员名 或 对象.静态数据成员名(前提是可访问符为public)

示例:

用静态数据成员记录由同一类建立的对象的数量。

定义学生类,统计学生的信息:

  • 通过定义一个全局变量统计当前学生总数,全局变量可以实现对象的共享,但是没有权限的限制,导致其他的函数或者对象可以无限制修改,则会出现问题(不安全);
  • 使用static,利用普通成员变量进行统计,普通成员变量是本类某个对象独有的,类作用域,不能实现共享,外界修改不了(比较安全)。
int m_count = 0;//1、全局变量
//全局变量可以实现对象的共享,但是没有权限的限制,导致其他的函数或者对象可以无限制修改,则会出现问题(不安全)
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 << "总数" << m_count << endl;
	}
private:
	int m_num;
	char* m_name;
	char m_sex;
	static int m_count;//2、普通成员变量是本类某个对象独有的,类作用域,不能实现共享,外界修改不了(比较安全)
};
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、在类的成员函数中使用静态数据成员,静态数据成员之前没有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、若类中含有静态成员,则该成员不在能本类中开辟空间,静态数据成员不占类的大小,不能在构造函数中初始化。

class A
{
public:
	//A():m_a(1),m_b(2),m_c(3){}//m_c不能在构造函数中初始化
	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、静态属性的类型是int,short,char,并且是const,可以在类中直接初始化

class Bar
{
private:
static const int nameSize = 20; // ok;
static const char name[nameSize]="xiao cheng bar"; // error;
};

 6、静态数据成员的类型可以是其所属类,而非static数据成员只能被声明为该类的指针

class Bar
{
private:
std::string _name;
private:
static Bar sm_bar; // ok;
private:
Bar m_bar; // error;
Bar *pb; // ok;
};

总结:

1、设计静态数据成员目的是信息共享和信息交流

2、类的静态数据成员为所有类对象所共享,不属于某个具体的实例

3、类的静态数据成员必须在类外定义,定义时不添加static关键字,不能在构造函数的初始化列表中创建

4、类的静态数据成员类型是int,short,char,long long,并且是const,可以在类中直接初始化,也可以在类外初始化

5、在类的成员函数中使用静态数据成员,静态数据成员之前没有this

6、当类的静态数据成员为公有时,可以在外部函数使用:类名::静态数据成员名 或 对象.静态数据成员名,可以在类体中定义自身的静态类型对象

三、静态方法 

函数成员说明为静态,将与该类的不同对象无关。静态函数成员的调用,在对象之外可以采用下面的方式:

类名::函数名 或 对象名.函数名

与静态数据成员相反,为使用方便,静态函数成员多为公有。

class Object
{
private:
static int num;
private:
int value;
public:
Object(int val = 0):value(val),num(val) {}// error;静态属性只能在类外初始化
Object(int val):value(val)
{
num = 1; // 不是初始化,是赋值
}
void print()
{
cout<<"value: "<<value<<" num: "<<num<<endl;
}
static void show() // 静态函数 not this
{
cout<<"value: "<<value<<" num: "<<num<<endl;
}
static void fun(Object &obj) // const // 不能定义为常方法。
{
cout<<obj.value<<" "<<num<<endl;
}
};
int Object::num = 0;

 静态成员函数没有this指针,因此在静态成员函数显式地使用this指针都将导致编译时刻错误。试图访问隐式使用this指针所指向的非静态数据成员也会导致编译时刻错误。

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 << "总数" << m_count << endl;
	}
	//在static函数中,没有this指针,所以不能直接输出非静态数据成员
	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指针来接收,不管是用哪个对象来调用static,本质使用当前对象的类型Student来调用
	Student::Show(s2);//right,不用特别去声明成员调用此函数
	//Student::Print();//error,非静态只能用对象来调用,非static中,有this指针,必须通过对象来调用
}

 总结:

一个常规的成员函数声明描述了三件在逻辑上相互不同的事情:

  • 该函数能访问类声明的私用部分。
  • 该函数位于类的作用域之中。
  • 该函数必须由一个对象去激活(有一个this指针)。

将一个函数声明为友元可以使它只具有第一种性质。

将一个函数声明为static可以使它只具有第一种和第二种性质。文章来源地址https://www.toymoban.com/news/detail-408552.html

到了这里,关于C++静态成员(static)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java 基础进阶篇(一)——— static 静态关键字与单例模式

    static:代表静态的意思,可以修饰成员变量,可以修饰成员方法。 static 修饰方法之后称为 静态方法(类方法) ,修饰成员变量之后称为 静态成员变量(类变量) 。 static 修饰后的成员变量, 可以被类的所有对象共享 (访问、修改) 。 静态成员变量 实例成员变量 概述 有

    2024年02月01日
    浏览(84)
  • C++—static关键字详解

    C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static。前者应用于普通变量和函数,不涉及类;后者主要说明static在类中的作用。 静态全局变量有以下特点: 1、该变量在全局数据区分配内存; 2、未经初始化的静态全局变量会被程序自动初始化为

    2024年02月15日
    浏览(36)
  • 【C++】static 关键字的特性 与 问题

    声明为 static的类成员 称为 类的静态成员 用 static 修饰的成员变量 ,称之为 静态成员变量 ; 用 static 修饰的成员函数 ,称之为 静态成员函数 。 静态成员变量 一定要在 类外进行初始化 。 下面一段代码证明 上述定义: 输出结果: 从代码可以看出,静态成员变量需要在 类

    2024年02月14日
    浏览(46)
  • C++ -- 学习系列 static 关键字的使用

    static 是 C++ 中常用的,被 static 修饰的变量只会在 静态存储区 (常量数据也存放在这里) 被分配一次内存,生命周期与整个程序一样,随着程序的消亡而消亡。 1. 在文件中定义的 静态全局变量 2. 在函数中定义的静态变量 3. 类的静态成员变量 4. 静态类对象 5. 类的静

    2024年02月09日
    浏览(49)
  • 【学习笔记】C++ 中 static 关键字的作用

    在 C/C++ 中, static 在不同的应用场景下,有不同的作用,这里总结一下,避免在使用时弄混。 我按照以下的逻辑来分类 static 的作用场景 static 作用在变量上 static 作用在全局变量上:限制全局变量在本文件上 static 作用在局部变量上:即使离开变量作用域,也保存变量

    2024年02月09日
    浏览(53)
  • [开发语言][c++]:Static关键字和全局变量

    写在前面: 如果您只是想回顾或了解一下static和全局变量的异同点,那么下面的总结将满足您的需求。 如果您是一位初学者或对二者的使用模棱两可,建议您读完该篇文章,相信这一篇将解答完您对于static以及全局变量的所有疑惑。 如有问题或建议欢迎评论 or 私信

    2024年01月20日
    浏览(56)
  • 在C++和C中static关键字的用法,在C++和C中const关键字的用法

    1、在C++和C中static的用法 答:static表示存储类型,修饰数据类型。在C语言中,static修饰局部变量,内存分配在静态区,生命周期延长,作用域不变。static修饰全局变量,内存分配在静态区,作用域被局限于本文件,不能被extern引用。static修饰函数,不能被exter

    2024年02月10日
    浏览(38)
  • 重学C++系列之const与static关键字分析

            本篇幅讲解const与static,主要围绕在类的范围内叙述,包括作用和使用场景等。         1、const修饰的成员变量,成员变量初始化后不能再修改。         2、const修饰的成员函数,成员函数不可以修改成员变量,也不能间接修改。         3、static修饰的成员

    2024年02月15日
    浏览(44)
  • 【C++】const、static关键字和构造函数初始化

    💗个人主页💗 ⭐个人专栏——C++学习⭐ 💫点击关注🤩一起学习C语言💯💫 目录 1. const修饰成员函数 1.1 语法格式 1.2 权限放大缩小 1.3 思考 1.4 解答 2. 再谈构造函数 2.1 构造函数体赋值 2.2 初始化列表 2.3 explicit 3. static成员 3.1 静态变量 3.2 静态函数 3.3 静态成员变量

    2024年02月19日
    浏览(46)
  • C/C++ static关键字详解(最全解析,static是什么,static如何使用,static的常考面试题)

    目录 一、前言  二、static是什么? 三、static修饰的对象是什么?   四、C 语言中的 static  🍎static的C用法  🍉static的重点概念  🍐static修饰局部变量  💦static在修饰局部变量和函数的作用  🍓static修饰全局变量和函数 💦static在修饰全局变量和函数的作用

    2024年02月05日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包