[4] C++高级编程

Axian / 2024-03-18 / 原文

Day1

常量补充

//--Day1.cpp
#pragma region 常量补充
    // 常对象和常函数
    const Student S1{ 10010, "张三", 1500 };
    S1.GetID();
     S1.SetID(10015); //调用非常函数会报错
#pragma endregion

//-- Student.h
#pragma once
#include <iostream>

class Student
{
protected:
	int ID;
	std::string Name;
	
	// 类中有const成员变量,初始化只能使用初始化列表
	// 构造函数中必须给常量成员做初始化,否则会报错
	const int Num;

public:
	static int Count;
	
	Student();
	Student(int ID, std::string Name, int Num);

	inline int GetID() const { return ID; }
	inline void SetID(int ID) { this->ID = ID; }

	inline std::string GetName() const { return Name; }
	inline void SetName(std::string Name) { this->Name = Name; }
};

// int Student::Count = 0;  // 语法错误

静态成员函数和静态成员

Day.cpp
 #pragma region 静态成员函数和静态成员
    // 静态 static

    // 静态成员在使用之前必须初始化(静态成员初始化有自己独特的方式)
    // 静态成员变量可以直接通过类访问(::),不用必须创建对象
    // 静态成员变量既可以通过类访问,也可以通过对象访问(. ->)
    // 本质 静态成员变量  是所有对象共享的
    Student::Count = 100;

    Student S1;
    cout << S1.Count << endl;

    Student S2;
    cout << S2.Count << endl;

    Student::Count = 500;
    cout << S1.Count << endl;
    cout << S2.Count << endl;

    S1.Count = 1000;
    cout << S1.Count << endl;
    cout << S2.Count << endl;

    cout << &S1.Count << endl;
    cout << &S2.Count << endl;
    cout << &Student::Count << endl;

    // 作用  同一个类不同对象共享 
    // 提供一种方式,可以统计当前类有多少个对象(构造++,析构--)
    // Set   Get  
    cout << Student::GetCount() << endl;
    {
        Student* S1 = new Student();
        Student S2;
        cout << Student::GetCount() << endl;
    }
    cout << Student::GetCount() << endl;

    // 静态成员函数
    // 在普通成员函数前加static
    // 静态成员函数中不允许访问非静态的成员变量和成员函数
    // 在普通成员函数中可以访问静态成员变量和静态成员函数
   
    // 继承中的静态
    // 父类对象和子类对象的静态成员变量地址是一致的
    Student S1;
    Pupil P1;

    cout << &S1.Count << endl;
    cout << &P1.Count << endl;

    cout << "End" << endl;

#pragma endregion
Student.h.cpp
 #pragma once
#include <iostream>

class Student
{
protected:
	int ID;
	std::string Name;
	
	// 类中有const成员变量,初始化只能使用初始化列表
	// 构造函数中必须给常量成员做初始化,否则会报错
	const int Num;

	

public:
	static int Count;
	

	Student();
	Student(int ID, std::string Name, int Num);

	inline int GetID() const { return ID; }
	inline void SetID(int ID) { this->ID = ID; }

	inline std::string GetName() const { return Name; }
	inline void SetName(std::string Name) { this->Name = Name; }

	inline static int GetCount() { 
		return Count;
	}

	void Test() const;

	int GetNum() const;

	virtual ~Student();
};

// int Student::Count = 0;  // 语法错误

//-- cpp
#include "Student.h"


int Student::Count = 0; // 推荐使用这种方式

Student::Student()
	: ID(0), Name(""), Num(0)
{
	Count++;
}

Student::Student(int ID, std::string Name, int Num)
	: Num(Num)
{
	this->ID = ID;
	this->Name = Name;
	Count++;
}

void Student::Test() const
{
	// ID = 10012; // 当前对象的属性不能修改
	GetID(); // 在一个常函数中可以调用另外一个常函数
	// SetID(10015); // 在一个常函数内部不允许调用非常函数

	


	// 创建一个临时对象(可以调用临时对象的非常量成员)
	// 如果创建的是const临时对象,依然需要遵循上面的规则
	Student S1;
	S1.ID = 10015;

}

int Student::GetNum() const
{
	return Num;
}

Student::~Student()
{
	Count--;
}

设计模式-单例模式

C++各类设计模式及实现详解

Day.cpp
 #pragma region 单例模式
    // 设计模式

    // 设计模式使简单的问题复杂化,使复杂的问题简单化

    // 单例模式  整个程序的声明周期内,某一个类有且只有同一个对象
    // 1、把构造函数变成private  ->  防止在类的外部进行new对象
    // 2、创建一个private的静态成员,用来存储唯一的对象
    // 3、定义一个public的静态函数,用来访问提供的唯一的对象
    
    {
        cout << GameInstance::GetInstance()->GetID() << endl;
        GameInstance::GetInstance()->SetID(10050);
        cout << GameInstance::GetInstance()->GetID() << endl;
    }
     Test();
    // 添加其他成员
    
    // 
    // delete销毁  (static变量是游戏开始就存在,直到游戏结束才会被销毁)
    // 表现上 单例类的析构貌似没有调用

    // 练习 
    // 一个公司只有一台打印机,员工A打印加薪申请,员工B打印简历,打印机需要记录打印了哪些份文件
    auto Printer = PrinterManager::GetManager();
    Printer->Print("加薪申请");
    Printer->Print("简历");
    Printer->Print("加班申请");
    Printer->ShowHistory();
    Printer->ClearHistory();
    Printer->ShowHistory();

    
#pragma endregion
GameInstance.h.cpp
 #pragma once
#include <iostream>

    // 1、把构造函数变成private  ->  防止在类的外部进行new对象
    // 2、创建一个private的静态成员,用来存储唯一的对象
    // 3、定义一个public的静态函数,用来访问提供的唯一的对象

class GameInstance
{
private:
    GameInstance();

    // 推荐使用指针
    static GameInstance* Instance; 

    int ID;

public:
    inline int GetID() const { return ID; }
    inline void SetID(int ID) { this->ID = ID; }

    virtual ~GameInstance()
    {
        if (Instance)
        {
            delete Instance;
            Instance = nullptr;
            std::cout << "调用析构" << std::endl;
        }
    }

    // static和const无法连用
    static GameInstance* GetInstance() 
    {
        if (!Instance) // 如果Instance是一个空指针,需要new一个对象
        {
            Instance = new GameInstance();
        }
        return Instance;
    }
};
//--cpp
#pragma once
#include <iostream>

    // 1、把构造函数变成private  ->  防止在类的外部进行new对象
    // 2、创建一个private的静态成员,用来存储唯一的对象
    // 3、定义一个public的静态函数,用来访问提供的唯一的对象

class GameInstance
{
private:
    GameInstance();

    // 推荐使用指针
    static GameInstance* Instance; 

    int ID;

public:
    inline int GetID() const { return ID; }
    inline void SetID(int ID) { this->ID = ID; }

    virtual ~GameInstance()
    {
        if (Instance)
        {
            delete Instance;
            Instance = nullptr;
            std::cout << "调用析构" << std::endl;
        }
    }

    // static和const无法连用
    static GameInstance* GetInstance() 
    {
        if (!Instance) // 如果Instance是一个空指针,需要new一个对象
        {
            Instance = new GameInstance();
        }
        return Instance;
    }
};

运算符重载

Day.cpp
 #pragma region 运算符重载
    Complex C1(2, 5);
    Complex C2(7, 10);
    Complex C3 = C1 + C2;  // 调用成员函数重载的第一种方式
     C3 = C1.operator+(C2); // 调用成员函数重载的第二种方式
    C3.Display();


    // 运算符重载的必要性:
        // 类型是自定义的(结构体、类),默认不支持很多运算符
    // + 重载  模仿现有类型推断自定义类型
        // 全局友元函数 Complex operator+(const Complex& A, const Complex& B)
        // 成员函数 Complex Complex::operator+(const Complex& Another)  默认参数有this,相当于全局友元函数中的A
        // C3 = C1 + C2  如果两者同时存在,不会编译报错,但是优先选择成员函数
        // C3 = C1.operator+(C2) 只会调用成员函数,不会调用全局友元

#pragma endregion
Complex.h.cpp
 //-- .h
#pragma once
class Complex
{
	friend Complex operator+(const Complex& A, const Complex& B);

protected:
	int Real; // 实部
	int Imagine; // 虚部

public:
	Complex();
	Complex(int Real, int Imagine);

	void Display();

	// +重载
	 Complex operator+(const Complex& Another);
};
//-- .cpp
#include "Complex.h"
#include <iostream>

using namespace std;

Complex::Complex()
	:Real(1),Imagine(1)
{
}

Complex::Complex(int Real, int Imagine)
	:Real(Real),Imagine(Imagine)
{
}

Complex Complex::operator+(const Complex& Another)
{
	return Complex(this->Real + Another.Real,this->Imagine + Another.Imagine);
}


void Complex::Display()
{
	cout << Real << "+" << Imagine << "i" << endl;
}

Day2