C++ 特殊成员

简介: C++ 特殊成员

C++特殊成员

const成员

  • const修饰的数据成员
  • 初始化必须采用初始化参数列表
  • 不能被修改
  • 构造函数必须要初始化常数据成员
  • const修饰的成员函数
  • 写法上要注意: const修饰是写在函数后面
  • const成员函数不能修改任何的数据成员
  • 如果实在是要在常成员函数中修改该数据,用mutable修饰数据成员即可
  • 常成员函数可以普通函数同时存在
  • const对象
  • const修饰的对象
  • 常对象只能调用常成员函数
#include <iostream>
using namespace std;
class MM
{
public:
  MM(int age) :name("小芳"), num(4323)
  {
    this->age = age;
  }
  MM(string name, int age, int num) :name(name), age(age), num(num)
  {
  }
  //MM() {}   常数据必须要初始化,错误
  //MM() = default;   //正确,可以构造无参对象
  void print()
  {
    age = 18;
    //num = 11;   //不能修改常数据成员
    cout << this->name << " " << this->num << " " << this->age << endl;
    cout << "普通函数" << endl;
  }
  //常成员函数: const写在函数后面
  void print() const 
  {
    cout << this->name << " " << this->num << " " << this->age << endl;
    cout << "常成员函数" << endl;
  }
  void printData() const 
  {
    //age = 23;      //常成员函数,不能修改数据成员
    cout << this->name << this->num << this->age << endl;
  }
  void test() {}
protected:
  //常数据成员
  const string name;
  const int num;
  int age;       //mutable 可修改的意思
  
};
int main() 
{
  MM mm("小丽", 18, 1001);
  //如果普通函数和常成员函数同名
  mm.print();           //普通对象优先调用普通函数
  const MM object(18);
  object.print();         //常对象只能调用常成员函数
  object.printData();
  //object.test();          //错误,常对象只能调用常成员函数
  return 0;
}

static成员

static成员不属于某一个单独对象,是属于类的,通俗一点讲,是所有对象的共享的,static成员依然受权限

satic成员他的访问可以不需要对象(用类名限定的方式去访问)

  • static数据成员
  • 初始化必须在类外初始化
  • 类实现的时候不需要用static修饰了
  • static成员函数
  • static写在修饰函数的前面
  • 类外实现也不需要static修饰
  • 静态函数中没有this指针
  • 静态成员函数的访问问题
  • 静态成员函数访问静态成员 是可以直接访问
  • 静态成员函数访问非静态数据成员,必须通过指定对象的方式
  • 静态成员函数传参
  • 在静态成员函数定义对象去访问
#include <iostream>
#include <string>
using namespace std;
class User
{
public:
  User(string name = "默认")
  {
    this->count++;      //类中访问
    this->m_count++;
  }
  void print() 
  {
    cout << name << " " << count << endl;
  }
  //void test() {}  不能和普通函数形参重载效果,会造成重定义问题
public:
  static void test();
  static void testData(User& object);
private:
  string name;
public:
  static int count;
  int m_count = 0;
};
//必须在类外面做初始化,不需要static修饰了
int User::count = 0;
void User::test() 
{
  cout << "count:" << count << endl;
  //cout << "m_count:" << m_count << endl;  //静态成员函数中不能直接调用非静态成员
  cout << "静态函数" << endl;
}
void User::testData(User& object)
{
  cout << object.m_count << endl;   //传参
  User mm;
  cout << mm.m_count << endl;     //创建对象
}
int main() 
{
  cout << User::count << endl;      //static 成员访问不需要对象
  User object[3];
  cout << User::count << endl;
  User mm;
  cout << mm.count << endl;
  cout << User::count << endl;      //可以用类名访问,前提是权限没问题
  cout << mm.m_count << endl;       //不能用类名
  User::test();             //因为存在这种调用,所以静态成员函数中不能存在this指针
  mm.test();                
  return 0;
}

单例设计模式

什么是设计模式

  • 模式: 套路  ---> 写代码的习惯
  • 设计模式:前人总结的具有代表的套路
    (官方说法:又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结)
  • 设计模式究极目标: 通过增加代码的形式去减少因为变化而要修改原代码的问题(维护问题)

单例设计模式

什么是单例设计模式

保证整个类的使用只有一个对象

  • 多线程网络资源初始化
  • 回收站机制
  • 任务管理器
  • 日志管理

如何实现单例设计模式

  • 构造函数私有化
  • 提供一个全局的静态方法,访问唯一对象
  • 类中定义一个而静态指针,指向唯一对象

单例设计模式实现代码

懒汉式

在类中创建一个对象(只有用的才去创建)

:线程不安全

/*
- 构造函数私有化
- 提供一个全局的静态方法,访问唯一对象
- 类中定义一个而静态指针,指向唯一对象
*/
#include <iostream>
using namespace std;
class SingleTon 
{
public:
  //类中定义一个而静态指针,指向唯一对象
  static SingleTon* m_singleTon;
  //提供一个全局的静态方法,访问唯一对象
  static SingleTon* GetInstance() 
  {
      if (m_singleTon == nullptr)
      {
        m_singleTon = new SingleTon;
      }
      return m_singleTon;
  }
private:
  SingleTon()
  {
    cout << "构造对象...." << endl;
    m_singleTon = nullptr;
  }
};
SingleTon* SingleTon::m_singleTon=nullptr;
int main() 
{
  SingleTon* p1 = SingleTon::GetInstance();
  cout << "p1:" << p1 << endl;
  SingleTon* p2 = SingleTon::GetInstance();
  cout << "p2:" << p2 << endl;
  return 0;
}

饿汉式

全局创建的一个对象(饥不择食,用不用都去创建)

:线程安全

/*
- 构造函数私有化
- 提供一个全局的静态方法,访问唯一对象
- 类中定义一个而静态指针,指向唯一对象
*/
#include <iostream>
using namespace std;
class SingleTon 
{
public:
  //类中定义一个而静态指针,指向唯一对象
  static SingleTon* m_singleTon;
  //提供一个全局的静态方法,访问唯一对象
  static SingleTon* GetInstance() 
  {
    return m_singleTon;
  }
private:
  SingleTon()
  {
    cout << "构造对象...." << endl;
  }
};
SingleTon* SingleTon::m_singleTon=new SingleTon;
int main() 
{
  SingleTon* p1 = SingleTon::GetInstance();
  cout << "p1:" << p1 << endl;
  SingleTon* p2 = SingleTon::GetInstance();
  cout << "p2:" << p2 << endl;
  return 0;
}

单例设计优缺点

  • 优点
  • 内存中只有一个对象,节省内存空间
  • 避免频繁创建和销毁对象,提高性能
  • 避免对共享的资源的多重占用,简化访问
  • 缺点
  • 不适用变化频繁的对象
  • 长时间不使用对象,导致系统回收掉

C++多文件写法

  • 一个类一个模块
  • 声明写在.h
  • 实现写在.cpp
  • 声明和试下写在一起 .hpp
  • 头文件包含尽量在.cpp完成
  • 设计项目时候,头文件形成交叉包含,说明思想有问题,自己重新设计代码
  • 不要为了拆分而拆分
  • 静态数据成员多文件写法
error LNK2019: 
无法解析的外部符号 "public: __cdecl MM::~MM(void)" (??1MM@@QEAA@XZ),函数 main 中引用了该符号
//1.无法解析: 没有实现这个函数
//2. "public: __cdecl MM::~MM(void)" (??1MM@@QEAA@XZ)
//2.1 public:权限
//2.2 __cdecl:调用准备
//2.2 MM::~MM(void): 函数名
error C2572: “MM::initData”: 重定义默认参数 : 参数 1
//重定义问题: 多次定义

小试牛刀

//自己总结特殊成员的特性,写出测试代码交上来
目录
相关文章
|
1月前
|
存储 编译器 C++
【C++】深入探索类和对象:初始化列表及其static成员与友元(一)
【C++】深入探索类和对象:初始化列表及其static成员与友元
|
1月前
|
编译器 C语言 C++
C++入门3——类与对象2-2(类的6个默认成员函数)
C++入门3——类与对象2-2(类的6个默认成员函数)
23 3
|
1月前
|
存储 编译器 C++
C++入门3——类与对象2-1(类的6个默认成员函数)
C++入门3——类与对象2-1(类的6个默认成员函数)
30 1
|
1月前
|
存储 编译器 数据安全/隐私保护
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解2
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解
29 3
|
1月前
|
编译器 C++
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解1
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解
45 3
|
1月前
|
C++
【C++】深入探索类和对象:初始化列表及其static成员与友元(二)
【C++】深入探索类和对象:初始化列表及其static成员与友元
|
1月前
|
编译器 C++
【C++】深入探索类和对象:初始化列表及其static成员与友元(三)
【C++】深入探索类和对象:初始化列表及其static成员与友元
|
6月前
|
存储 Serverless 数据安全/隐私保护
C++ 类的成员函数和数据成员的技术性探讨
C++ 类的成员函数和数据成员的技术性探讨
73 0
|
3月前
|
编译器 C++ 索引
C++虚拟成员-虚函数
C++虚拟成员-虚函数
|
3月前
|
编译器 C++
virtual类的使用方法问题之C++类中的非静态数据成员是进行内存对齐的如何解决
virtual类的使用方法问题之C++类中的非静态数据成员是进行内存对齐的如何解决