逆向初级-C++(三)

1、什么是封装:
将函数定义到结构体内部,就是封装。
2、什么是类:
带有函数的结构体,称为类。
3、什么是成员函数:
结构体里面的函数,称为成员函数。

#include
#include
#include

struct Student
{
    int a;
    int b;
    int c;

    int plus()
    {
        return a+b+c;
    }
};

void main()
{
    Student s = {1,2,3};
    int r = s.plus();    //r=6

    system("pause");
    return ;
}

1、什么是this指针

1、this指针是编译器默认传入的,通常都会使用ecx进行参数的传递。
2、你用或者不用,它都在那。

3、this指针不能做++-等运算,不能重新被赋值。
4、this指针不占用结构体的宽度。

2、this指针的使用

struct sclass
{
    int a;
    int b;

    void Init(int a,int b)
    {
        this->a=a;
        this->b= b;
    }
    void Print()
    {
        printf("%d %d" ,a,b);
    }
};

1、构造函数

1、与类同名,没有返回值
2、创建对象的时候执行,主要用于初始化
3、可以有多个(最好有一个无参的),称为重载,其他函数也可以重载
4、编译器不要求必须提供

2、析构函数总结:
1、只能有一个析构函数不能重载
2、不能带任何参数
3、不能带返回值
4、主要用于清理工作
5、编译器不要求必须提供

#include
#include
#include

struct Student
{
    int a;
    int b;
    int c;

    Student()
    {
        printf("没有参数的构造函数\n");
    }

    Student(int a,int b,int c)
    {
        this->a = a;
        this->b = b;
        this->c = c;
        printf("有参数的构造函数\n");
    }

    ~Student()
    {
        printf("析造函数\n");
    }

    int plus()
    {
        return a+b+c;
    }
};

void main()
{
    Student s1;
    Student s2(1,2,3);

    system("pause");
    return ;
}

1、什么是继承?

继承就是数据的复制
2、为什么要用继承?

减少重复代码的编写

#include
#include
#include

struct X
{
    int a;
    int b;
};

struct Y:X
{
    int c;
    int d;
};

struct Z:Y
{
    int e;
    int f;
};

void main()
{

    system("pause");
    return ;
}

1、我们可以在什么地方创建对象?

void Max()
{
    Person p;
}
#include
#include
#include

class Person
{
private:
    int x;
    int y;

public:
    Person()
    {
        printf("Person()执行了\n");
    }

    Person(int x,int y)
    {
        printf("Person(int x,int y)执行了\n");
        this->x = x;
        this->y = y;
    }

    ~Person()
    {
        printf("~Person()执行了\n");
    }
};

void main()
{
    Person* p = new Person(1,2);

    delete p;

    system("pause");
    return ;
}

2、new delete的本质:

总结:
new = malloc +构造函数

1、引用就是变量的”别名”

基本类型
intx= 1;
int &p=x;
p=2;                    //p就是x
printf("%d \n",x);

类
Person p;
Person &px=p; I
px.x= 10;
printf("%d \n",p.x);

指针
int******i= (int******)1;
int******&r=i;
r= (int******)2;
printf("%d \n",r);

数组
int arr[]={1,2,3};
int (&px)[3] = arr;
px[0]= 100;
//px就是arr
printf("%d \n",arr[0);

2、引用类型与指针的区别

1、引用必须赋初始值,且只能指向一个变量,”从-而终”。
2、对引用赋值,是对其指向的变量赋值,而并不是修改引用本身的值。
3、对引用做运算,就是对其指向的变量做运算,而不是对引用本身做运算。
4、引用类型就是一个”弱化了的指针”。

#include
#include
#include

class Person
{
private:
    int Age;
    int Sex;
public:
    //父类有参构造函数
    Person(int Age,int Sex)
    {
        this->Age = Age;
        this->Sex = Sex;
    }

    void SetAge(int Age)
    {
        this->Age = Age;
    }
    void SetSex(int Sex)
    {
        this->Sex = Sex;
    }
    void print()
    {
        printf("%d %d\n",Age,Sex);
    }
};

class Teacher:public Person
{
private:
    int Level;

public:
    // :Person(Age,Sex)使用父类的有参构造函数
    Teacher(int Age,int Sex,int Level):Person(Age,Sex)
    {
        this->Level = Level;
    }
    void SetLevel(int Level)
    {
        this->Level = Level;
    }
};

void main()
{
    Teacher t(1,2,3);
    t.print();

    system("pause");
    return ;
}

1、纯虚函数

2、什么是多态?
多态就是可以让父类指针有多种形态。
C++中是通过虚函数实现的多态性。

#include
#include
#include

class Person
{
private:
    int Age;
    int Sex;
public:
    Person(int Age,int Sex)
    {
        this->Age = Age;
        this->Sex = Sex;
    }

    void SetAge(int Age)
    {
        this->Age = Age;
    }
    void SetSex(int Sex)
    {
        this->Sex = Sex;
    }
    //虚函数
    virtual void print()
    {
        printf("%d %d\n",Age,Sex);
    }
};

class Teacher:public Person
{
private:
    int Level;

public:
    Teacher(int Age,int Sex,int Level):Person(Age,Sex)
    {
        this->Level = Level;
    }
    void SetLevel(int Level)
    {
        this->Level = Level;
    }
    //重写父类的print()
    void print()
    {
        Person::print();
        printf("%d\n",Level);
    }
};

//多态,参数是父类的引用
void MyPrint(Person& p)
{
    p.print();
}

void main()
{
    Teacher t(1,2,3);
    MyPrint(t);

    system("pause");
    return ;
}
Number operator++();
Number operator--0;
Number operator+(const Number& p);
Number operator-(const Number& p);
Number operator*(const Number& p);
Number operator/(const Number& p);
bool operator>(const Number& p);
bool operator
#include
#include
#include

class Number
{
private:
    int x;
    int y;

public:
    Number(int x,int y)
    {
        this->x = x;
        this->y = y;
    }
    //运算符重载
    bool operator>(Number& n)
    {
        return this->x > n.x && this->y > n.y;
    }
};

void main()
{

    Number n1(1,2);
    Number n2(3,4);
    bool r = n1 > n2;

    system("pause");
    return ;
}

1、在函数中使用模版

函数模板的格式:

template 返回类型 函数名(参数列表)
{
    函数体
}

#include
#include
#include

template
void Sort(T* arr ,int nLength)
{
    int i;
    int k;
    for(i=0;i arr[k+1])
            {
                T temp = arr[k];
                arr[k] = arr[k+1];
                arr[k+1] = temp;
            }
    }
};

void main()
{
    int arr[] = {1,3,2,5,4};
    Sort(arr,5);

    system("pause");
    return;
}

2、在结构体/类中使用模版
类模板的格式为:

templateclass 类名
{

}
#include
#include
#include

template
struct Base
{
    T x;
    T y;

    M a;
    M b;

    int Max()
    {
        if(x>y)
        {
            return x;
        }
        else
        {
            return y;
        }
    }

    char Min()
    {
        if(a base;

    base.x =1;
    base.y =2;
    base.a=3;
    base.b=4;

    int r = base.Max();

    system("pause");
    return;
}

1、如果不需要深拷贝,不要自己添加拷贝构造函数。

2、如果你添加了拷贝构造函数,那么编译器将不在提供,所有的事情都需要由新添加的函数自己来处理:

MyObject(const MyObject& obj) Base(obj)
{
    printf(°拷贝构造函数执行了\n");
    this->x= obj.x;
    this->y= obj.y;
 }

对象拷贝

#include
#include
#include

class CBase
{
private:
    int z;
public:
    CBase(){}
    CBase(int Z)
    {
        this->z = z;
    }
};

class CObfject:public CBase
{
private:
    int x;
    int y;
public:
    CObfject(){}
    CObfject(int x,int y,int z):CBase(z)
    {
        this->x = x;
        this->y = y;
    }
};

void main()
{
    CObfject obj(1,2,3);

    CObfject objNew(obj);

    CObfject* p = new CObfject(obj);

    system("pause");
    return;
}

浅拷贝

#include
#include
#include

class CObject
{
private:
    int m_length;
    char* m_strBuffer;
public:
    CObject(){}
    CObject(const char* str)
    {
        m_length = strlen(str) + 1;
        m_strBuffer = new char[m_length];
        memset(m_strBuffer,0,m_length);
        strcpy(m_strBuffer,str);
    }
    ~CObject()
    {
        delete[] m_strBuffer;
    }
};

void main()
{
    CObject oldobj("derek");

    CObject newobj(oldobj);  //浅拷贝

    system("pause");
    return;
}

深拷贝

#include
#include
#include

class CObject
{
private:
    int m_length;
    char* m_strBuffer;
public:
    CObject(){}
    CObject(const char* str)
    {
        m_length = strlen(str) + 1;
        m_strBuffer = new char[m_length];
        memset(m_strBuffer,0,m_length);
        strcpy(m_strBuffer,str);
    }
    //自己编写的拷贝构造函数
    CObject(const CObject& obj)
    {
        m_length = obj.m_length;
        m_strBuffer = new char[m_length];
        memset(m_strBuffer,0,m_length);
        strcpy(m_strBuffer,obj.m_strBuffer);
    }
    ~CObject()
    {
        delete[] m_strBuffer;
    }
};

void main()
{
    CObject oldobj("derek");

    CObject newobj(oldobj);   //深拷贝

    system("pause");
    return;
}

1、对象拷贝的两种形式:

2、赋值运算符的问题

赋值运算符”=”与拷贝构造函数-一样, 都是将成员的值直接复制,都是”浅拷贝”

3、重载赋值运算符:

#include
#include
#include

class CBase
{
private:
    int m_nLength;
    char* m_pBuffer;
public:
    CBase(){
        m_nLength = 0;
        m_pBuffer = NULL;
    }
    CBase(char* szBuffer)
        {
            this->m_nLength = strlen(szBuffer)+1;
            m_pBuffer = new char[m_nLength];
            strcpy(m_pBuffer,szBuffer);
        }
    CBase& operator=(const CBase& ref)
    {
        m_nLength = ref.m_nLength;
        if(m_pBuffer!=NULL)
            delete[] m_pBuffer;
        m_pBuffer = new char[m_nLength];
        memcpy(m_pBuffer,ref.m_pBuffer,m_nLength);
        return *this;
    }
    virtual ~CBase(){
        delete[] m_pBuffer;
    }
};

void main()
{
    CBase c1("china"),c2("derek");
    c1 = c2;

    system("pause");
    return;
}

1、面向对象设计中的static之静态数据成员:

#include
#include
#include

class CBase
{
private:
    int x;
    int y;
    static int z;     //私有的全局变量,CBase类的所有对象公用
public:
    void SetValue(int a)
    {
        z=a;
    }
    int GetValue()
    {
        return z;
    }
};
//静态成员的初始化
int CBase::z = 0;

void main()
{
    CBase c1,c2;
    c1.SetValue(10);
    int b = c2.GetValue();
    printf("%d\n",b);    //10

    system("pause");
    return;
}
#include
#include
#include

class CBase
{
public:
    CBase(int x,int y);
    static int GetSum();    //静态成员函数
private:
    int x,y;
    static int Sum;
};

int CBase::Sum = 0;

CBase::CBase(int x,int y)
{
    this->x=x;
    this->y=y;
}
int CBase::GetSum()
{
    return Sum;
}

void main()
{
    CBase::GetSum();

    system("pause");
    return;
}

2、单例模式

一个类只能创建一个对象

#include
#include
#include

class CSingleton
{
public:
    static CSingleton* GetInstance()
    {
        if(m_pInstance == NULL)
            m_pInstance = new CSingleton();
        return m_pInstance;
    }
private:
    CSingleton(){}
    static CSingleton* m_pInstance;    //定义静态成员
};

CSingleton* CSingleton::m_pInstance = NULL;  //初始化静态成员

void main()
{
    //两个实例指向的地址一模一样
    CSingleton* p1 = CSingleton::GetInstance();
    CSingleton* p2 = CSingleton::GetInstance();

    system("pause");
    return;
}

Original: https://www.cnblogs.com/derek1184405959/p/14636611.html
Author: zhang_derek
Title: 逆向初级-C++(三)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/536463/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • C++中的三种继承关系

    先看类中声明成员时的三种访问权限 public : 可以被任意实体访问 protected : 只允许子类及本类的成员函数访问 private : 只允许本类的成员函数访问 在类继…

    C++ 2023年5月29日
    068
  • C++11多线程

    在C++11之前,C++语言层面是不支持多线程的,想利用C++实现并发程序,借助操作系统的API实现跨平台的并发程序存在着诸多不便。在C++11中,终于提供了多线程的标准库,提供了…

    C++ 2023年5月29日
    052
  • CLion之C++框架篇-安装工具,基础框架的搭建(一)

    背景 日常学习C++,也就是看看书、在vim里写写代码。在日常项目开发中,也是边看书(一是系统性理解、二是找找有什么更好的代码编写方式)边写代码,会顺带看看别人的代码怎么写的? 日…

    C++ 2023年5月29日
    060
  • C/C++中的常量指针与指针常量(转)

    常量指针 常量指针是指向常量的指针,指针指向的内存地址的内容是不可修改的。 常量指针定义”const int p=&a;”告诉编译器,p是常量,不能将*p作…

    C++ 2023年5月29日
    039
  • Kruskal算法(二)之 C++详解

    在含有n个顶点的连通图中选择n-1条边,构成一棵极小连通子图,并使该连通子图中n-1条边上权值之和达到最小,则称其为连通网的最小生成树。 例如,对于如上图G4所示的连通网可以有多棵…

    C++ 2023年5月29日
    057
  • 【C++服务端技术】对象池

    代码没贴全,就少一个锁头文件,可以做设计参考 设计思想就是维护一个空闲链表,没有用的就重新申请,有的话就拿链表的头,使用完又还给空闲链表。 /* 一个分配固定大小内存的内存池,使用…

    C++ 2023年5月29日
    066
  • c++如何遍历删除map/vector里面的元素

    新技能Get! 对于c++里面的容器, 我们可以使用iterator进行方便的遍历. 但是当我们通过iterator对vector/map等进行修改时, 我们就要小心了, 因为操作…

    C++ 2023年5月29日
    088
  • Lua & C++

    Lua 与 C++ 交互 ## 提供系统级别Lua API 提供系统级别API需要对Lua源码进行修改 ### Lua源码编译 [LuaResourceCode]:https://…

    C++ 2023年5月29日
    062
  • 当C++遇到iOS应用开发—LRUCache缓存

    本文着重介绍如何在XCODE中,通过C++开发在iOS环境下运行的缓存功能。算法基于LRU(最近最少使用)。有关lru详见:http://en.wikipedia.org/wiki…

    C++ 2023年5月29日
    055
  • 解决c++中delete后内存系统不回收

    一般new出来的内存,delete掉后。 此时如果看top内存没有减少,则可以使用下面函数让系统强制回收。 #include malloc_trim(0); Original: h…

    C++ 2023年5月29日
    079
  • C++检测和定位内存泄漏

    1、首先需要宏定义一下new运算符 解释: new(a, b, c) T; 会被解释成一个函数调用operator new(sizeof(T), a, b, c)。这是C++就有的…

    C++ 2023年5月29日
    070
  • C++智能指针原理

    简介 智能指针就是对指针进行封装,使其提供特有的功能。 unique_ptr:封装了原始指针使其只能在同一时刻被同一对象拥有,并且在离开作用域时会自动销毁。 shared_ptr:…

    C++ 2023年5月29日
    079
  • c++反射技术

    https://www.cnblogs.com/lizhanwu/p/4428990.htmlhttps://www.cnblogs.com/leijiangtao/p/12059…

    C++ 2023年5月29日
    064
  • Xcode 导出C++项目在其他电脑执行

    先找到C++项目的可执行文件的位置 https://blog.csdn.net/qq_34759481/article/details/82700587 关于存储和加载文件的目录,…

    C++ 2023年5月29日
    054
  • LLVM Constant Value to c++ value

    auto llval = b.getInt32(-1); std::cout << llval->getZExtValue() << "\n…

    C++ 2023年5月29日
    072
  • c++11 auto 与 decltype 详解

    一. auto简介 编程时候常常需要把表达式的值付给变量,需要在声明变量的时候清楚的知道变量是什么类型。然而做到这一点并非那么容易(特别是模板中),有时候根本做不到。为了解决这个问…

    C++ 2023年5月29日
    063
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球