老生常谈c++中的静态成员

 更新时间:2021年7月21日 15:00  
有时候需要类的一些成员与类本身相关联,而不是与类的每个对象相关联。比如类的所有对象都要共享的变量,这个时候我们就要用到类的静态成员,今天通过实例代码给大家详细介绍,需要的朋友参考下吧

引言

有时候需要类的一些成员与类本身相关联,而不是与类的每个对象相关联。比如类的所有对象都要共享的变量,这个时候我们就要用到类的静态成员。

声明类的静态成员

声明静态成员的方法是使用static关键字。

static成员可以是public也可以是private的。

例如,定义一个类表示银行的账户记录:

class Account{
public:
    //其他非静态函数及数据成员
    //静态函数
    static double get_rate(){ return interestRate; }
    static void set_rate(double r){ interestRate = r; }
private:
    static double interestRate;//该类的所有对象公用同一个利率
    //其他static private函数
    //其他非static 函数及数据成员
};

Note:

  • 类的静态成员存在于任何对象之外,对象中不包含任何与静态数据成员有关的数据。
  • 静态成员函数不与任何对象绑定到一起,不能在静态成员函数中使用this指针。静态成员函数不能被声明为const。

使用类的静态成员

使用作用域运算符::直接访问静态成员。

double r;
r = Account::get_rate();

虽然静态成员不属于类的任何对象,但仍然可以通过类的对象访问静态成员。

Account ac1;
Account *ac2 = &ac1;
double r = ac1.get_rate();
r = ac2->get_rate();

成员函数可以直接使用静态成员,不需要作用域运算符。

定义静态成员

定义静态成员函数

类的静态成员函数既可以定义在类的外部也可以定义在类的内部(注意定义和声明的区别)。

当在类的外部定义静态成员函数时,不能使用static关键字,static关键字只在类内部该静态成员函数的声明处使用。否则重复。

当在类的外部定义静态成员函数时,必须指明该函数所属的类,如:

class Account{
public:
    //其他非静态函数及数据成员
    //静态成员函数
    static double get_rate(){ return interestRate; }
    static void set_rate(double r){ interestRate = r; }
    static void print();//静态成员函数声明
private:
    static double interestRate;//该类的所有对象公用同一个利率
    //其他static private函数
    //其他非static 函数及数据成员
};
//定义静态函数时不需要使用static关键字,否则重复。另外指明该函数所属的类。
void Account::print(){
    //要完成的工作
}

定义静态数据成员

因为静态数据成员不属于类的任何一个对象,所以他们并不是在创建类的对象的时候被定义的。不能在类的内部初始化静态数据成员,必须在类的外部定义和初始化每个静态数据成员。

double Account::interestRate = initRate();//不用static关键字

静态数据成员的类内初始化

前面提到,类的静态数据成员不应该在类的内部被初始化。但若静态数据成员同时还是constexpr类型,则可以在类内初始化。

即使一个常量静态成员在类内被初始化了,通常也应该在类的外部定义一下该成员,但类外定义使不能再指定初始值,因为在类内已经提供了初始值。

静态数据成员的特殊应用场景

1.静态成员独立于任何对象,因此,静态数据成员的类型可以是他所属的类类型,非静态数据成员只能声明为他所属的类的指针或引用。
例如:

class Person{
public:
    //...
private:
    static Person p; //正确,静态数据成员可以是不完全类型
    Person *p1;     //正确:指针成员和引用可以是不完全类型
    Person &p2      //正确
    Person p3;      //错误:数据成员必须是完全类型。
};//在此之前,class Person之后,Person类都是不完全类型,因只声明完但还没有定义完

2.可以使用静态成员作为默认实参

class Screen{
public:
    Screen& clear(char = bkground);
private:
    static const char bkground;
}

非静态数据成员不能作为默认实参,因为非静态数据成员属于对象,对象的值是在运行时确定的,但默认参数却是在编译时确定的,也就是说,默认参数确定时还没有真正的对象被创建,因此不能用非静态数据成员作为默认参数,否则引发错误。

声明:
c++ Basic是对《C++ Primer 第五版》的个人总结与疑难解释。
如果想要深入了解更多,请支持正版。

到此这篇关于老生常谈c++中的静态成员的文章就介绍到这了,更多相关c++静态成员内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

相关文章

  • 深入学习C++智能指针之shared_ptr与右值引用的方法

    智能指针的核心实现技术是引用计数,每使用它一次,内部引用计数加1,每析构一次内部的引用计数减1,减为0时,删除所指向的堆内存,今天通过本文给大家分享C++智能指针之shared_ptr与右值引用的方法,需要的朋友跟随小编一起看看吧...2021-07-13
  • 浅谈c++性能测试工具google benchmark

    本文将会介绍如何使用模板以及参数生成器来批量生成测试用例,简化繁琐的性能测试代码...2021-06-26
  • 详解C++实现匈牙利算法

    匈牙利算法是一种在多项式时间内求解任务分配问题的组合优化算法,并推动了后来的原始对偶方法。美国数学家哈罗德·库恩于1955年提出该算法。此算法之所以被称作匈牙利算法,是因为算法很大一部分是基于以前匈牙利数学家Dénes Kőnig和Jenő Egerváry的工作之上创建起来的...2021-06-17
  • C++实现LeetCode(37.求解数独)

    这篇文章主要介绍了C++实现LeetCode(37.求解数独),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下...2021-07-14
  • C++中NULL与nullptr的区别对比

    nullptr是c++11中的关键字,下面这篇文章主要介绍了C++中NULL与nullptr区别的相关资料,对大家来说还是挺实用的,需要的朋友可以参考下...2021-05-16
  • 一文搞懂C++中的四种强制类型转换

    很多朋友向小编了解C语言中怎么进行强制类型转换呢?在这小编告诉大家强制类型转换可以分为两种,一种是隐式类型转换一种是显示类型转换,下面通过示例代码给大家介绍下,需要的朋友参考下吧...2021-07-07
  • C++实现聊天小程序

    这篇文章主要为大家详细介绍了C++实现聊天小程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-07-01
  • C++/CLI在vs上的安装和初步使用教程

    本文给大家介绍C++/CLI在vs上的安装和初步使用,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧...2021-07-02
  • 深入浅析C++ traits技术

    traits就是提取“被传进的对象”对应的返回类型,让同一个接口实现对应的功能。因为STL的算法和容器是分离的,两者通过迭代器链接,本文通过实例代码给大家介绍C++ traits技术,感兴趣的朋友一起看看吧...2021-05-30
  • C++解析特殊符号tab、换行符号实例代码

    这篇文章主要给大家介绍了关于C++解析特殊符号tab、换行符号的相关资料,这个功能在我们日常开发中经常会遇到,需要的朋友可以参考下...2021-05-16
  • 详解C++的反调试技术与绕过手法

    反调试技术,恶意代码会用它识别自身是否被调试,或者让调试器失效,给反病毒工程师们制造麻烦,拉长提取特征码的时间线,本章将具体总结常见的反调试基础的实现原理以及如何过掉这些反调试手段,从而让我们能够继续分析恶意代码...2021-06-24
  • 线段树详解以及C++实现代码

    线段树在一些acm题目中经常见到,这种数据结构主要应用在计算几何和地理信息系统中,这篇文章主要给大家介绍了关于线段树以及C++实现的相关资料,需要的朋友可以参考下...2021-07-19
  • c++多线程为何要使用条件变量详解

    多线程是多任务处理的一种特殊形式,下面这篇文章主要给大家介绍了关于c++多线程为何要使用条件变量的相关资料,需要的朋友可以参考下...2021-06-04
  • C++实现LeetCode(51.N皇后问题)

    这篇文章主要介绍了C++实现LeetCode(51.N皇后问题),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下...2021-07-14
  • 在Visual Studio Code中配置C++编译环境的问题

    关于Visual Studio Code对C++环境的配置方法应该有好多种,我这里用到了其中的两种,具体内容详情文中给大家详细介绍,对Visual Studio Code配置C++编译环境相关知识感兴趣的朋友一起看看吧...2021-07-05
  • 从c++标准库指针萃取器谈一下traits技法(推荐)

    本篇文章基于gcc中标准库源码剖析一下标准库中的模板类pointer_traits,并且以此为例理解一下traits技法,对c++ traits技法源码分析感兴趣的朋友跟随小编一起看看吧...2021-07-14
  • C++实现二分法求方程近似解

    这篇文章主要为大家详细介绍了C++实现二分法求方程近似解,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-05-09
  • C++ 实现桶排序的示例代码

    桶排序或所谓的箱排序,是一个排序算法,工作的原理是将数组分到有限数量的桶子,本文详细的介绍了如何实现,感兴趣的可以了解一下...2021-07-12
  • C++基于灰度图上色GrayToColorFromOther的实现

    本文主要介绍了C++基于灰度图上色GrayToColorFromOther的实现,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧...2021-07-19
  • VS2019实现C++的第一个MFC程序

    本文主要介绍了VS2019实现C++的第一个MFC程序,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-06-07