17. C++ static、const 和 static const 类型成员变量声明以及初始化

1. C++ static、const 和 static const 类型成员变量声明以及初始化
  • const 定义的常量在超出其作用域之后其空间会被释放;

  • static 定义的静态常量在函数执行后不会释放其存储空间;

1.2 static

static 表示的是静态的

  • 类的静态成员函数、静态成员变量是和类相关的,而不是和类的具体对象相关的。即使没有具体对象,也能调用类的静态成员函数和成员变量。一般类的静态函数几乎就是一个全局函数,只不过它的作用域限于包含它的文件中。

  • 在 C++ 中,static 静态成员变量不能在类的内部初始化。在类的内部只是声明,定义必须在类定义体的外部,通常在类的实现文件中初始化。

  • static 关键字只能用于类定义体内部的声明中,定义时不能标示为 static。

  • 在 C++ 中,const 成员变量也不能在类定义处初始化,只能通过构造函数初始化列表进行,并且必须有构造函数。

  • const 数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的。因为类可以创建多个对象,不同的对象其 const 数据成员的值可以不同。所以不能在类的声明中初始化 const 数据成员,因为类的对象没被创建时,编译器不知道 const 数据成员的值是什么。

  • const 数据成员的初始化只能在类的构造函数的初始化列表中进行。要想建立在整个类中都恒定的常量,应该用类中的枚举常量来实现,或者static const。

class Test{
public:Test():a(0){}enum {size1=100,size2=200};
private:const int a;        // 只能在构造函数初始化列表中初始化static int b;       // 在类的实现文件中定义并初始化const static int c; // 与 static const int c;相同。
};int Test::b=0;       // static成员变量不能在构造函数初始化列表中初始化,因为它不属于某个对象。
const int Test::c=0; // 注意:给静态成员变量赋值时,不需要加static修饰符,但要加cosnt。
  • const 成员函数主要目的是防止成员函数修改对象的内容。即 const 成员函数不能修改成员变量的值,但可以访问成员变量。当访问成员函数时,该函数只能是 const 成员函数。

  • static 成员函数主要目的是作为类作用域的全局函数。不能访问类的非静态数据成员。类的静态成员函数没有 this 指针,这导致:

    • 不能直接存取类的非静态成员变量,调用非静态成员函数。

    • 不能被声明为 virtual。

1.3 关于 static、const、static const、const static 成员的初始化问题

类里的const成员初始化:

在一个类里建立一个 const 时,不能给他初值。

class foo{
public:foo():i(100){}
private:const int i = 100;//error!!!
};
//或者通过这样的方式来进行初始化
foo::foo():i(100){}
1.3.2 类里的static成员初始化

类中的 static 变量是属于类的,不属于某个对象,它在整个程序的运行过程中只有一个副本,因此不能在定义对象时 对变量进行初始化,就是不能用构造函数进行初始化,其正确的初始化方法是:

数据类型 类名::静态数据成员名 = 值;
class foo{
public:foo();
private:static int i;
};int foo()::i=20;
  • 初始化在类体外进行,而前面不加static,以免与一般静态变量或对象相混淆。

  • 初始化时不加该成员的访问权限控制符private、public等

  • 初始化时使用作用域运算符来表明它所属的类,因此,静态数据成员是类的成员而不是对象的成员。

1.3.3 类里的 static const 和 const static 成员初始化
class Test{
public:static const int mask1;const static int mask2;
};
const Test::mask1 = 0xffff;
const Test::mask2 = 0xffff;
// 它们的初始化没有区别,虽然一个是静态常量一个是常量静态。静态都将存储在全局变量区域,其实最后结果都一样。可能在不同编译器内,不同处理,但最后结果都一样。

完整实例

#ifdef A_H_
#define A_H_
#include <iostream>
using namespace std;class A{
public:A(int a);staticvoid print();    // 静态成员函数
private:static int aa;         // 静态数据成员的声明staticconst int count; // 常量静态数据成员(可以在构造函数中初始化)const int bb;          // 常量数据成员
};int A::aa=0;               // 静态成员的定义+初始化
const int A::count=25;     // 静态常量成员定义+初始化
A::A(int a):bb(a){         // 常量成员的初始化aa+=1;
}
void A::print(){cout<<"count="<<count<<endl;cout<<"aa="<<aa<<endl;
}
#endif
int main(){A a(10);A::print();//通过类访问静态成员函数a.print();//通过对象访问静态成员函数
}
2. c++类的静态成员
2.1 静态数据成员
  • 在类中,静态成员可以实现多个对象之间的数据共享,并且使用静态数据成员还不会破坏隐藏的原则,即保证了安全性。因此,静态成员是类的所有对象中共享的成员,而不是某个对象的成员

  • 使用静态数据成员可以节省内存,因为它是所有对象所公有的,因此,对多个对象来说,静态数据成员只存储一处,供所有对象共用。静态数据成员的值对每个对象都是一样,但它的值是可以更新的。只要对静态数据成员的值更新一次,保证所有对象存取更新后的相同的值,这样可以提高时间效率。

静态数据成员的使用方法和注意事项如下:

  • 静态数据成员在定义或说明时前面加关键字 static

  • 静态成员初始化与一般数据成员初始化不同。

静态数据成员初始化的格式如下:

<数据类型> <类名>::<静态数据成员名> = <值>

注意:

  • **初始化在类体外进行,而前面不加static,**以免与一般静态变量或对象相混淆。
  • 初始化时不加该成员的访问权限控制符private,public等。
  • 初始化时使用作用域运算符来标明它所属类,因此,静态数据成员是类的成员,而不是对象的成员。
2.2 静态成员函数

静态成员函数和静态数据成员一样,它们都属于类的静态成员,它们都不是对象成员。因此,对静态成员的引用不需要用对象名。

在静态成员函数的实现中不能直接引用类中说明的非静态成员,可以引用类中说明的静态成员如果静态成员函数中要引用非静态成员时,可通过对象来引用。

#include …
class M{
public:M(int a){A=a;B+=a;}  static void f1(M m);
private:int A;static int B;
};void M::f1(M m)
{cout<<"A="<<m.A<<endl;cout<<"B="<<B<<endl;
}int M::B=0;int main()
{M P(5),Q(10);M::f1(P); //调用时不用对象名M::f1(Q);
}

调用静态成员函数使用如下格式:

<类名>::<静态成员函数名>(<参数表>);
3. C++ 中各种类型的成员变量的初始化方法

C++各种不同类型成员根据是否static、时候const类型的初始化方法不尽相同。

#pragma once
class Test
{
private:int var1;// int var1 = 4; 错误的初始化方法const int var2 ;// const int var2 =2; 错误的初始化方法static int var3;// static int var3 = 3; 错误,只有静态常量int成员才能直接赋值来初始化static const int var4 = 4; //正确,静态常量成员可以直接初始化    static const int var5;//也可以在类外初始化,可以被const
public:Test(void);~Test(void);
};int Test::var3 = 3; //静态成员的正确的初始化方法
// int Test::var1 = 1; 错误静态成员才能初始化
// int Test::var2 = 2; 错误
// int Test::var4 = 4; // 错误的方法,提示重定义
Test::Test(void):var1(1),var2(2) // 正确的初始化方法,var3(3)不能在这里初始化
{var1 = 1; //正确, 普通变量也可以在这里初始化// var2 = 2; 错误,因为常量不能赋值,只能在 "constructor initializer (构造函数的初始化列表)" 那里初始化var3 = 4; //这个赋值是正确的,不过因为所有对象一个静态成员,所以会影响到其他的,这不能叫做初始化了吧
}
Test::~Test(void){}

有些成员变量的数据类型比较特别,它们的初始化方式也和普通数据类型的成员变量有所不同。这些特殊的类型的成员变量包括:

  • a. 常量型成员变量
  • b. 引用型成员变量
  • c. 静态成员变量
  • d. 整型静态常量成员变量
  • e. 非整型静态常量成员变量

对于常量型成员变量和引用型成员变量的初始化,必须通过构造函数初始化列表的方式进行。在构造函数体内给常量型成员变量和引用型成员变量赋值的方式是行不通的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/618216.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ASP.NET进销存系统源码

ASP.NET进销存系统源码 功能介绍&#xff1a; 财务 销售清单&#xff0c;填写销售单&#xff0c;客户管理&#xff0c;添加客户资料 销售 销售清单&#xff0c;填写销售单&#xff0c;客户管理&#xff0c;添加客户资料 仓库 仓库结存&#xff0c;仓库盘点&#xff0c;盘点结…

初学unity学习七天,经验收获总结

初学unity七天&#xff0c;经验收获总结 学习就是认识新观念和新想法的过程。 假如人们始终以同一种思维方式来考虑问题的话&#xff0c;那么始终只会得到同样的结果。 因为我对你讲述的许多内容是你以前从未接触过的&#xff0c;所以我建议你&#xff0c;在你还没有做之前&…

确保CentOS系统中的静态HTTP服务器的数据安全

确保CentOS系统中的静态HTTP服务器的数据安全是一项重要的任务&#xff0c;它有助于保护网站免受未经授权的访问、数据泄露和其他安全威胁。以下是一些关键步骤和最佳实践&#xff0c;以确保CentOS系统中静态HTTP服务器的数据安全&#xff1a; 限制访问权限确保只有授权用户可…

Springboot+vue整合 支付宝沙箱支付

可以完成的功能&#xff1a; 一、拉起支付 二、异步回调 三、掉单处理 四、超时关闭 五、订单退款

使用ffmpeg对视频进行静音检测

1 原始视频信息 通过ffmpeg -i命令查看视频基本信息 ffmpeg version 6.1-essentials_build-www.gyan.dev Copyright (c) 2000-2023 the FFmpeg developersbuilt with gcc 12.2.0 (Rev10, Built by MSYS2 project)configuration: --enable-gpl --enable-version3 --enable-sta…

uniapp项目 插件市场下载pdd-date-picker【年月日选择器】路径不对的问题

从HBuilder插件市场下载pdd-date-picker年月日插件之后 按照t它的官方问的进行引入你会发现路径不对&#xff0c;我们需要再自己的项目中重新去查看一下路径 下面是官方文档给出的路径 import pddDatePicker from ../../components/pdd-date-picker/index.vue我们需要将上面的…

ASP.NET房屋中介管理系统源码

ASP.NET房屋中介管理系统源码 房屋中介系统是非常实用的&#xff0c;不仅可以详细的记录房源信息、用户信息等&#xff0c; 同时本系统能够自动去查找和客户需求匹配的房源&#xff0c;可以方便客户同时提高使用者的工作质量与效率。

D25XB80-ASEMI开关电源桥堆D25XB80

编辑&#xff1a;ll D25XB80-ASEMI开关电源桥堆D25XB80 型号&#xff1a;D25XB80 品牌&#xff1a;ASEMI 封装&#xff1a;GBJ-5&#xff08;带康铜丝&#xff09; 特性&#xff1a;插件、整流桥 平均正向整流电流&#xff08;Id&#xff09;&#xff1a;25A 最大反向击…

新版云进销存ERP销售库存仓库员工管理系统源码

新版云进销存ERP销售库存仓库员工管理系统源码 系统介绍&#xff1a;2022版本,带合同报价单打印&#xff0c;修复子账号不显示新加客户的BUG&#xff0c;还有其他方面的优化。 简单方便。 功能强大&#xff0c;系统采用phpMYSQL开发&#xff0c;B/S架构&#xff0c;方便随地使用…

面向零信任架构的访问安全态势评估

伴随着“云大物移”等新兴 IT 技术的快速发展&#xff0c;企业数字化转型使得 IT 业务的网络环境更加复杂多样&#xff0c;企业数字资源的安全防护正面临着前所未有的压力与威胁。零信任安全架构放弃了传统基于“边界”的安全模型&#xff0c;以访问上下文的安全态势感知为基础…

Python解包列表批量赋值技巧

一、引言 众所周知&#xff0c;我们可以在Python中通过下标如lst[1]来对列表进行解包&#xff0c;或者用*lst进行解包&#xff0c;但是如果你遇到下面的问题该如何解决呢&#xff1f; 有如下列表&#xff0c;我们要获取列表中的前二个元素和最后一个元素&#xff0c;组成一个…

为什么不直接public,多此一举用get、set,一文给你说明白

文章目录 1. 封装性&#xff08;Encapsulation&#xff09;2. 验证与逻辑处理3. 计算属性&#xff08;Computed Properties&#xff09;4. **跟踪变化&#xff08;Change Tracking&#xff09;5. 懒加载与延迟初始化&#xff08;Lazy Initialization&#xff09;6. 兼容性与未来…

如何查询慢 SQL 产生的原因

如何查询慢 SQL 产生的原因 &#xff08;1&#xff09;分析 SQL 执行计划&#xff08;explain extended&#xff09;&#xff0c;思考可能的优化点&#xff0c;是否命中索引等。 &#xff08;2&#xff09;没有索引或者没有用到索引(这是查询慢最常见的问题&#xff0c;是程序…

Nightingale 夜莺监控系统 - 部署篇(1)

Author&#xff1a;rab 官方文档&#xff1a;https://flashcat.cloud/docs 目录 一、概述二、架构2.1 中心机房架构2.2 边缘下沉式混杂架构 三、环境四、部署4.1 中心机房架构部署4.1.1 MySQL4.1.2 Redis4.1.3 Prometheus4.1.4 n9e4.1.5 Categraf4.1.6 验证4.1.7 配置数据源 4…

条款23:宁以 non-member、non-friend 替换 member 函数

假设一个表示web浏览器的类&#xff1a; class WebBrowser { public:...void clearCache();void clearHistory();void removeCookies();void clearEverything(); // 调用clearCache,clearHistory,removeCookies };当然&#xff0c;这个也可以通过非成员函数调用适当的成员函数…

红队打靶练习:HOLYNIX: V1

目录 信息收集 1、arp 2、netdiscover 3、nmap 4、nikto whatweb 目录探测 1、gobuster 2、dirsearch 3、dirb 4、feroxbuster WEB sqlmap 1、爆库 2、爆表 3、爆列 4、爆字段 后台登录 1、文件上传 2、文件包含 3、越权漏洞 反弹shell 提权 总结 信息…

Spring整理-Spring Bean的生命周期

Spring Bean的生命周期涉及多个阶段,从Bean的定义到其销毁。在这个过程中,Spring容器负责创建、初始化、使用和最终销毁Bean。了解这个生命周期有助于更好地管理Bean的行为和资源使用。 Spring Bean生命周期的主要阶段 实例化(Instantiation):容器首先创建Bean的实例。填充…

数据分析---SQL(2)

目录 SQL语句的执行顺序是什么举例说明SQL如何实现去重操作举例说明如何将时间戳转为yyyy-MM-dd形式如何将yyyy-MM-dd改为yyyyMMdd形式如何求两个yyyyMMdd形式的日期差几天SQL语句的执行顺序是什么 在SQL中,一条SQL语句的执行顺序如下: FROM子句:首先,执行FROM子句,确定要…

【Java】——期末复习题题库(九)

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

matplotlib教程(一)—— 入门基础

前言 Matplotlib 是 Python 的绘图库&#xff0c;它能让使用者很轻松地将数据图形化&#xff0c;并且提供多样化的输出格式&#xff1b;它可以绘制线图、散点图、等高线图、条形图、柱状图、3D 图形、甚至是图形动画等 在使用它之前&#xff0c;应导入&#xff1a;import matp…