C++——静态成员和成员指针

简介: C++——静态成员和成员指针

文章目录

静态成员

静态成员变量

代码示例

静态成员函数

代码示例

单例模式

代码示例

成员指针

成员变量指针

成员函数指针

代码示例


静态成员

静态成员变量

静态成员变量:


class 类名{
    static 数据类型 变量;//声明
  };
  数据类型 类名::变量 = 初值;//定义和初始化


  • 普通成员变量属于对象,而静态成员变量不属于对象。
  • 静态成员变量和全局变量类似,存储在全局区,可以把静态成员变量理解成被限制在类中使用的全局变量。
  • 使用方式:
类名::静态成员变量;//推荐
  对象.静态成员变量;//和上面等价


代码示例

  • static.cpp
#include <iostream>
using namespace std;
class A{
public:
    //普通成员变量在构造函数中定义和初始化
    A(int data=0):m_data(data){}
    int m_data;
    static int s_data;//声明
};
//静态成员变量的定义和初始化要在类的外部完成
int A::s_data = 100;//定义
int main(void)
{
    A a(200);
    //静态成员变量不属于对象
    cout << sizeof(a) << endl;//4
    //静态成员变量可以通过"类名::"去访问
    cout << A::s_data << endl;//100
    //普通的成员变量必须通过对象去访问
    cout << a.m_data << endl;//200
    //静态成员变量也可以通过对象去访问
    cout << a.s_data << endl;//ok,100
    A a2(a);
    a2.m_data = 222;
    a2.s_data = 111;//A::s_data = 111
    cout << a.s_data << endl;//111
    cout << a.m_data << endl;//200
    return 0;
}


  • 执行结果

20200213094441711.png

静态成员函数

class 类名{
    static 返回类型 函数名(形参表){...} 
  };


  • 静态成员函数没有 this 指针,也没有常属性。
  • 使用:

类名::静态成员函数(实参表);//推荐
  对象.静态成员函数(实参表);//和上面等价


  • 注:在静态成员函数中只能访问静态成员,不能访问非静态成员;在非静态成员函数中既可以访问静态成员也可以访问非静态成员。

代码示例

  • static_func.cpp
#include <iostream>
using namespace std;
class A{
public:
    A(int data=0):m_data(data){}
    static void func1(void){
        cout << "静态成员函数" << endl;
        cout << s_data << endl;
        //cout << m_data << endl;
    }
    void func2(void){
        cout << "非静态成员函数" << endl;
        cout << s_data << endl;
        cout << m_data << endl;
    }
    int m_data;
    static int s_data;//声明
};
int A::s_data = 100;//定义
int main(void)
{
    A::func1();
    A a(200);
    a.func2();//A::func2(&a)
    return 0;
}


  • 执行结果

20200213094741437.png

单例模式

概念: 一个类只允许存在唯一的对象,并提供它的访问方法。


创建思路:


  • 禁止在类的外部创建对象:私有化构造函数。
  • 类的内部维护唯一的对象:静态成员变量。
  • 提供单例对象的访问方法:静态成员函数。

创建方式:


  • 饿汉式:无论用或者不用,程序启动即创建。
  • 懒汉式:用时创建,不用销毁。

代码示例

  • hungry.cpp
//单例模式:饿汉式
#include <iostream>
using namespace std;
class Singleton{
public:
    //3)使用静态成员函数获取单例对象
    static Singleton& getInstance(void){
        return s_instance;
    }
    void print(void)const{
        cout << m_data << endl;
    }
private:
    //1)私有化构造函数
    Singleton(int data=0):m_data(data){
        cout << "单例对象被创建了" << endl;
    }
    Singleton(const Singleton&);
private:
    int m_data;
    //2)使用静态成员变量表示唯一的单例对象
    static Singleton s_instance;
};
Singleton Singleton::s_instance(12345);
int main(void)
{
    cout << "main函数开始执行" << endl;
    //Singleton s(100);
    //Singleton* ps = new Singleton(100);
    Singleton& s1=Singleton::getInstance();
    Singleton& s2=Singleton::getInstance();
    Singleton& s3=Singleton::getInstance();
    cout << "&s1=" << &s1 << ",&s2=" <<
        &s2 << ",&s3=" << &s3 << endl;
    s1.print();
    s2.print();
    s3.print();
    return 0;
}


  • 执行结果

20200213095459118.png

  • lary.cpp


//单例模式:懒汉式
#include <iostream>
using namespace std;
class Singleton{
public:
    //3)使用静态成员函数获取单例对象
    static Singleton& getInstance(void){
        if(s_instance == NULL)
            s_instance=new Singleton(12345);
        s_count++;
        return *s_instance;
    }
    //单例对象不用即销毁
    //单例对象可能有多个使用者,应该是最后
    //一个使用者用release才去delete
    void release(void){
        if(--s_count == 0){
            delete s_instance;
            s_instance = NULL;
        }
    }
    void print(void)const{
        cout << m_data << endl;
    }
private:
    //1)私有化构造函数
    Singleton(int data=0):m_data(data){
        cout << "单例对象被创建了" << endl;
    }
    Singleton(const Singleton&);
    ~Singleton(void){
        cout << "单例对象被销毁了" << endl;
    }
private:
    int m_data;
    //2)使用静态成员变量表示唯一的单例对象
    static Singleton* s_instance;
    //计数:记录单例对象使用者的个数
    static int s_count;
};
Singleton* Singleton::s_instance = NULL;
int Singleton::s_count = 0;
int main(void)
{
    cout << "main函数开始执行" << endl;
    //Singleton s(100);
    //Singleton* ps = new Singleton(100);
    //s_count++ ==> 1
    Singleton& s1=Singleton::getInstance();
    //s_count++ ==> 2
    Singleton& s2=Singleton::getInstance();
    //s_count++ ==> 3
    Singleton& s3=Singleton::getInstance();
    cout << "&s1=" << &s1 << ",&s2=" <<
        &s2 << ",&s3=" << &s3 << endl;
    s1.print();
    s1.release();//--s_count,2
    s2.print();
    s3.print();
    s2.release();//--s_count,1
    s3.release();//--s_count,0 delete
    return 0;
}


  • 执行结果

20200213100432445.png

成员指针

成员变量指针

  • 定义
类型 类名::*成员指针变量名 = &类名::成员变量;


  • 使用
对象.*成员指针变量名;
对象指针->*成员指针变量名;


成员函数指针

  • 定义
返回类型 (类名::*成员函数指针)(形参表) = &类名::成员函数名;


使用

(对象.*成员函数指针)(实参表)
  (对象->*成员函数指针)(实参表)

 

“.*”称为直接成员解引用操作符
  “->*”称为间接成员解引用操作符


代码示例

  • memptr.cpp
#include <iostream>
using namespace std;
class Student{
public:
    Student(const string& name)
        :m_name(name){}
    void who(void){
        cout << "我叫" << m_name << endl;
    }
    string m_name;
};
int main(void)
{
    //成员变量指针
    string Student::*pname 
        = &Student::m_name;
    //成员函数指针
    void (Student::*pwho)(void) 
        = &Student::who;
    Student s("王建立");
    cout << s.*pname << endl;
    (s.*pwho)();
    return 0;
}


  • 执行结果

20200213100842138.png

相关文章
|
3天前
|
存储 程序员 C++
深入解析C++中的函数指针与`typedef`的妙用
本文深入解析了C++中的函数指针及其与`typedef`的结合使用。通过图示和代码示例,详细介绍了函数指针的基本概念、声明和使用方法,并展示了如何利用`typedef`简化复杂的函数指针声明,提升代码的可读性和可维护性。
19 0
|
29天前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
82 5
|
1月前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
86 4
|
2月前
|
存储 安全 编译器
在 C++中,引用和指针的区别
在C++中,引用和指针都是用于间接访问对象的工具,但它们有显著区别。引用是对象的别名,必须在定义时初始化且不可重新绑定;指针是一个变量,可以指向不同对象,也可为空。引用更安全,指针更灵活。
|
2月前
|
编译器 C语言 C++
C++入门3——类与对象2-2(类的6个默认成员函数)
C++入门3——类与对象2-2(类的6个默认成员函数)
38 3
|
2月前
|
存储 C++
c++的指针完整教程
本文提供了一个全面的C++指针教程,包括指针的声明与初始化、访问指针指向的值、指针运算、指针与函数的关系、动态内存分配,以及不同类型指针(如一级指针、二级指针、整型指针、字符指针、数组指针、函数指针、成员指针、void指针)的介绍,还提到了不同位数机器上指针大小的差异。
61 1
|
2月前
|
存储 编译器 C语言
C++入门2——类与对象1(类的定义和this指针)
C++入门2——类与对象1(类的定义和this指针)
43 2
|
2月前
|
存储 编译器 C++
C++入门3——类与对象2-1(类的6个默认成员函数)
C++入门3——类与对象2-1(类的6个默认成员函数)
46 1
|
2月前
|
存储 编译器 数据安全/隐私保护
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解2
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解
40 3
|
2月前
|
编译器 C++
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解1
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解
52 3