C++ 自定义类型

自定义类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Message.h
#pragma once
#include <string>

using namespace std;

class Message {

public:
// 构造函数
Message(int fromUserId, int toUserId, string& messageContent);
void SendMessage();
const int MessageId;
const int ToUserId;
const int FromUserId;
const string& MessageContent;
static inline int MsgContent {0};

private:
int createMessageId();
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "Message.h"
#include <iostream>
#include <random>

// 构造函数,成员初始化列表
Message::Message(int fromUserId, int toUserId, std::string &messageContent) :
FromUserId{ fromUserId },
ToUserId{ toUserId },
MessageContent{ messageContent },
MessageId{ createMessageId() } {
MsgContent += 1;
}

void Message::SendMessage() {
cout << "From:" << FromUserId << endl
<< "To:" << ToUserId << endl
<< "Message:" << MessageContent << endl
<< "MessageId:" << MessageId << endl;
}

int Message::createMessageId() {
std::random_device dev;
return dev();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 实际使用
#include "Message.h"
#include <iostream>
#include <string>

using namespace std;

Message* CreateMessage() {
string msgContent{"测试 class 嘟嘟。"};
// 这里 msgContent 传递引用到构造函数,而 msgContent 会在 CreateMessage 函数结束后被回收
// 所以实际上 msgContent 在 Message 的实例中无法访问
Message* msg{new Message(12, 34, msgContent)};
return msg;
}

int main() {
auto msg {CreateMessage()};
msg->SendMessage();
delete msg;
return 0;
}

访问修饰符

  • public 后定义的都是公开成员,可访问:
    • 该类中的函数
    • 子类的函数
    • 该类的实例
  • private 后定义的是私有成员 ,可访问:
    • 该类中的函数
  • protected 可访问:
    • 该类的函数
    • 子类的函数
  • 同一访问修饰符可在类里多次使用,比如多个 publc: 或多个 private

构造函数

  • 和类同名
  • 没有返回值
  • 如果没有定义,编译器会添加一个空的构造函数(如果任一构造函数,则不会添加)
  • 可以有多个参数不同的构造函数

成员初始化列表

  • 先于构造函数执行
  • const 类型成员变量不允许重新复制,只能在成员初始化列表中赋值
  • 可以调用自定义函数甚至是另一个构造函数

静态成员

  • static 关键字标记静态成员
  • 在同一类里只有一份实例
  • 可以在同一类型的不同实例间共享数据
  • C++17 以后可以使用 inline 关键字成为内联的静态成员变量
    • C++17 只能在类声明外部初始化 int Message::MsgCount{0};
  • 可以通过实例访问 msg->MsgCount
  • 可以通过类访问 Message::MsgCount 推荐使用这个

析构函数

1
2
3
4
5
6
7
8
//头文件,public节
~Message(); //析构函数的定义
UserInfo* userInfo;

//源码文件:
Message::~Message() { //析构函数的实现
delete userInfo
}
  • 释放对象时自动执行
    • delete someInstance
    • 栈帧自动释放
  • 用来做一些收尾工作, 比如释放引用对象,关闭数据库链接等
  • 原则
    • 凡是使用 new 创建的实例都需要自己手动 delete
    • 永远不要在析构函数里抛出异常
    • 只能有一个
    • 没有参数
    • 必须是 public

赋值运算符重载

将一个对象的值赋值给另一个对象

  • 不推荐使用这个特性

  • ```c++
    // 定义
    class MyClass {
    public:

    // 类的成员和其他方法
    
    // 赋值运算符重载
    MyClass& operator=(const MyClass& other) {
        // 实现赋值操作
        if (this != &other) {  // 避免自赋值
            // 复制 other 的数据到当前对象
            // ...
        }
        // 返回当前对象的引用
        return *this;
    }
    

    };

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    - ```c++
    // 使用
    int main() {
    MyClass obj1;
    obj1.data = 42;

    MyClass obj2;
    obj2.data = 10;

    // 使用赋值运算符重载
    obj2 = obj1;

    std::cout << "obj2.data: " << obj2.data << std::endl; // 输出 42
    return 0;
    }
  • 如果没有手动创建,编译器会自动生成一个赋值运算符函数

    • 默认的赋值运算符函数会把 obj1 的所有成员变量赋值给 obj2 obj2 = obj1
  • 可以使用 delete 手动删除

    • YourType operator= (const YourType& msg) = delete;

复制构造函数

  • 不推荐使用这个特性

  • 编译器默认生成

  • 复制一个实例

    • ```c++
      Message a(9);
      Message b{ a };
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30

      - 可以删除

      - `YourType(const YourType& obj) = delete`

      ### 单例模式

      - 保证一个类在一定范围里只有一个实例

      - ```c++
      class Message
      {
      public:
      Message(const Message& msg) = delete;
      void operator= (const Message& msg) = delete;
      ~Message() {
      //堆空间被释放后,把静态变量instance置为nullptr,以备下次重新创建新的对象
      instance = nullptr;
      }
      // 使用 getInstance 创建实例,不再手动调用 new
      static Message* getInstance() {
      if (instance == nullptr) {
      instance = new Message();
      }
      return instance;
      }
      private:
      inline static Message* instance{ nullptr };
      };

结构: struct

  • 来源于 C 语言

  • 类似 class

  • 默认成员都是 public

    • struct MyStruct
      {
          int a = 2;
          void func() {
              cout << "func:" << endl;
          }
      };
      int main() {
          MyStruct myStruct;
          myStruct.func();
      }
      
  • 常用来聚合数据

作者

大下坡

发布于

2023-11-09

更新于

2023-11-09

许可协议