美文网首页IT狗工作室
第6篇:C++ 静态成员和函数

第6篇:C++ 静态成员和函数

作者: 铁甲万能狗 | 来源:发表于2019-09-22 09:06 被阅读0次

在前面1-5篇中详细讲解一些类的示例,其中每个对象都有自己的数据成员数据集。 该类的每个成员函数都可以访问其类的任何对象的任何成员。在某些情况下,可能希望定义可以由该类的所有实例都能访问的公共数据字段。在C中也遇到这种情况,C源文件中的几个函数需要访问同一变量。 C的一种常见解决方案是同个源文件中定义所有函数,并且定义一个static变量.在源文件之外,变量名不可见。 这种方法非常有效,但是违反了我们在每个源文件中仅使用一个函数的原则。

C ++通过定义静态成员来解决该问题:这些静态成员是类的所有对象所共有的数据和函数,并且(在私有部分中定义时)在类外部无法访问。 这些静态成员是本章的主题。

静态成员不能定义为virtual函数。 虚拟成员函数是普通成员,因为它具有this指针。 由于静态成员函数没有此指针,因此无法将其声明为virtual。

静态数据

类的任何数据成员都可以声明为static; 无论是在类接口的public部分还是private部分中。 与为该类的每个对象一次又一次创建的非静态数据成员相反,此类数据成员仅创建和初始化一次。

程序启动后立即创建静态数据成员。 即使它们是在程序执行周期的最开始创建的,它们仍然是其类的真正成员。为了方便区分静态数据成员普通数据成员建议为静态数据成员的名称加上s_前缀。

公共静态数据成员是全局变量。 程序的所有代码都可以访问它们,只需使用其类名,范围解析运算符及其成员名即可。以下是详细的例子:
类接口:cone.hh文件

#include  <string>
class Cone
{
   std::string d_name;
    double d_radius;
    double d_height;
    double d_busLength;

public:
    static double s_pi;
    static int s_count;
    Cone(std::string, double, double);

    //计算体积
    double volume();

    //计算底面面积
    double bottom_area();

    //计算表面积
    double surface_area();

    //计算侧面积
    double side_area();

    //显示容积
    void display_volume();
};

如果没有其他初始化,则在创建第一个对象时,所有静态数据都会根据其声明的数据类型进行类内默认值初始化

静态数据成员的初始化:不能将其放在类接口中,一般来说,公共的静态数据成员是放在类接口外部进行初始化,方法是使用作用域运算符::来重新声明静态变量,以标识它属于哪个类,下面是一个很贴切的例子。
类实现:cone.cpp文件

#include "../header/cone.hh"
#include <iostream>
#include <math.h>

// 静态成员在类接口外初始化
int Cone::s_count = 0;
double Cone::s_pi = 3.14;

Cone::Cone(std::string name, double r, double h) : d_radius(r), d_height(h), d_name(name)
{

    s_count++;
    std::cout << "创建一个锥体,目前数量是" << s_count << std::endl;
    if (d_radius > 0 && d_height > 0)
    {
        d_busLength = sqrt(d_radius * d_radius + d_height * d_height);
    }
}
inline double Cone::volume()
{
    return s_pi * d_radius * d_radius * d_height / 1000 / 3.0;
}

inline void Cone::display_volume()
{
    std::cout << "锥体"<<d_name<<"的容积是" << volume() << "L" << std::endl;
}

double Cone::side_area()
{
    //公式PI*R*L
    return s_pi * d_radius * d_busLength;
}

inline double Cone::surface_area()
{
    return side_area() + bottom_area();
}

inline double Cone::bottom_area()
{
    //公式:PI*R*R
    return s_pi * d_radius * d_radius;
}

调用代码:

int main(int argc, char const *argv[])
{

    Cone c1 = {"N1", 43.5, 72.5};
    Cone c2 = {"N2", 52.77, 23.33};
    Cone c3 = {"N3", 47.5, 72.5};
    Cone c4 = {"N4", 32.77, 33.33};

    c1.display_volume();
    c2.display_volume();
    c3.display_volume();
    c4.display_volume();

    return 0;
}

而实际项目中,我们更倾向于将整个项目的所有类的静态数据成员集中在某个源文件当中(例如:st_data.cpp),然后在程序入口的源文件include这个st_data.cpp就可以了。

由于构造函数是为类的每个新对象调用的,因此构造函数不会初始化静态数据成员。 最多就是修改。 原因是静态数据成员在调用该类的任何构造函数之前就已经存在。 定义静态数据成员时,在任何成员函数之外都将对其进行初始化,就像对普通(非类)全局变量的初始化一样。

静态成员函数

除了静态数据成员,C ++还允许我们定义静态成员函数。与类的所有对象共享的静态数据类似,静态成员函数的特征如下。

  1. 静态成员函数可以访问其类的所有静态成员,也可以访问其类的对象的成员(包括private或public),但前提要指定一个该类的对象.
  2. 静态成员函数并没与其类的任何对象关联,因此它们没有this指针。
  3. 静态成员函数只能从类外部访问静态数据成员其他静态成员函数和任何其他函数。
  4. 静态成员函数可以被在类接口的public部分声明的其他静态成员函数调用,而无需指定其类的对象。以下示例说明了静态成员函数的这种特征:

下面的示例是为了上面的静态成员函数的特征的,我们在前文的Cone类接口中增加两个静态成员函数的声明
类接口

 class Cone{
      .....
     //显示侧面面积
    static void display_sideArea(Cone &);

    //显示表面积
    static void display_surfArea(Cone &);
}

类实现
很多情况下:我们可能需要用静态成员函数,调用它所属的类的某个实例的非静态数据成员 , 正是特征1所说的那样。特征2和3更不用说了,下面这些示例都是从类外调用

void Cone::display_sideArea(Cone &obj)
{
    std::cout << obj.d_name << "侧面积:" << obj.side_area() << std::endl;
}

void Cone::display_surfArea(Cone &obj)
{
    std::cout << obj.d_name << "表面积:" << obj.surface_area() << std::endl;
}

下面是静态成员函数调用同一个类的静态函数,正如上面特征4所述

void Cone::display_all(Cone &obj)
{
    std::cout << "型号:" << obj.d_name << std::endl;
    std::cout << "参数:"
              << "r " << obj.d_radius << " h " << obj.d_height << " l " << obj.d_busLength << std::endl;

    display_surfArea(obj);
    display_sideArea(obj);
}

调用代码

#include "./cone.cpp"
#include <iostream>
using namespace std;

int main(int argc, char const *argv[])
{

    Cone c1 = {"N1", 43.5, 72.5};
    Cone c2 = {"N2", 52.77, 23.33};
    Cone c3 = {"N3", 47.5, 72.5};
    Cone c4 = {"N4", 32.77, 33.33};

    c1.display_volume();
    c2.display_volume();
    c3.display_volume();
    c4.display_volume();

    Cone::display_sideArea(c1);
    Cone::display_surfArea(c2);

    Cone::display_all(c1);
    Cone::display_all(c2);
    return 0;
}

相关文章

  • C++ 面向对象模型初探(8)

    1. 成员变量和函数的存储 c++中“数据”和“处理数据的操作(函数)”是分开存储的 c++中的非静态数据成员直接...

  • [初学C++]静态成员

    静态成员变量和成员函数 在C++中,静态成员是属于整个类的而不是某个对象,静态成员变量只存储一份供所有对象共用。所...

  • c++语法2

    接上篇我们继续学习静态成员、友元函数、继承、多重继承,继承访问权限等 静态成员与友元函数:c++中静态成员与jav...

  • C++中对Const用法的总结

    1、C++函数声明时在后面加const的作用:非静态成员函数后面加const(加到非成员函数或静态成员后面会产生编...

  • 深入理解C++对象模型

    1. C++对象模型 所有的非静态数据成员存储在对象本身中。所有的静态数据成员、成员函数(包括静态与非静态)都置于...

  • linux c/c++ 面试题目整理(四)

    31、C++空类是多大?为什么会这样? 空类是1个字节,一个类中虚函数、成员函数(包括静态和非静态)和静态数...

  • C++ 静态成员函数

    通过将某个函数成员声明为 static,我们将使该函数独立于本类的任何具体对象。从静态函数内引用类成员,必须使用限...

  • 第6篇:C++ 静态成员和函数

    在前面1-5篇中详细讲解一些类的示例,其中每个对象都有自己的数据成员数据集。 该类的每个成员函数都可以访问其类的任...

  • C++11可调用对象包装器和绑定器

    可调用对象 在C++中,可以像函数一样调用的有:普通函数、类的静态成员、仿函数、lambda函数、类的成员函数、可...

  • 电商专业学习嵌入式软件开发第五十八天

    C++第四天 今天讲的内容有静态成员变量和静态成员函数、引用、继承、拷贝构造函数,最后还带着我们完成了一个超市管理...

网友评论

    本文标题:第6篇:C++ 静态成员和函数

    本文链接:https://www.haomeiwen.com/subject/jjasuctx.html