逆向初级-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++ 资源大全

    http://www.uml.org.cn/c++/201411145.asp http://ezlippi.com/blog/2014/12/c-open-project.htm…

    C++ 2023年5月29日
    045
  • 对类的理解(c++)

    介绍目录: 1.类成员 1.1 成员函数 1.2 构造函数 1.2.1 对构造函数的理解 1.2.2成员初始化列表 1.2.3必须使用成员初始化列表的几种情况 1.2.4对于拷贝构…

    C++ 2023年5月29日
    063
  • C++面试题1

    1,LeetCode给出一个 32 位的有符号整数,将这个整数中每位上的数字进行反转; 2,怎么判断一个变量是指针; Original: https://www.cnblogs.c…

    C++ 2023年5月29日
    051
  • GCC:/usr/lib/libstdc++.so.6: version GLIBCXX_3.4.15 not found

    源码编译升级安装了gcc后,编译程序或运行其它程序时,有时会出现类似/usr/lib64/libstdc++.so.6: version GLIBCXX_3.4.15' …

    C++ 2023年5月29日
    079
  • C++源码—lock_guard

    在 C++11 中,我们可以使用 mutex 来实现线程的同步,mutex 包括上锁和解锁两个步骤。 lock_guard 的功能也是实现线程同步,可以进一步偷懒以及避免在锁定期间…

    C++ 2023年5月29日
    030
  • Android jni c/c++线程通过CallVoidMethod调用java函数出现奔溃问题

    最近在移植网络摄像机里的p2p库到android平台,需要用到jni,最近在c线程了调用java函数的时候出现一个问题,假如在同一个线程调用java函数是没问题的,但在一个c线程了…

    C++ 2023年5月29日
    025
  • 侯捷c++系统工程师:全方位提升技能素养 侯捷C++视频全系列合集

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    C++ 2023年5月29日
    073
  • 【面试攻略】C++面试-边锋

    2020-11-26-边锋 1.说说你以前的架构2.C++11特性,好像问到了这个constexpr https://www.jianshu.com/p/5480c4a35d1d3…

    C++ 2023年5月29日
    053
  • 对指针和引用的理解(c++)

    1.指针 typedef说明一种新类型名,来代替已有类型名。 a.案例:typedef char String_t和#define String_d char 这两句在使用上的区别…

    C++ 2023年5月29日
    048
  • visual studio code的c++扩展

    posted @2020-08-20 10:07 kissrule 阅读(338 ) 评论() 编辑 Original: https://www.cnblogs.com/longc…

    C++ 2023年5月29日
    091
  • C++11 并发指南三(Lock 详解)

    C++11 标准为我们提供了两种基本的锁类型,分别如下: std::lock_guard,与 Mutex RAII 相关,方便线程对互斥量上锁。 std::unique_lock,…

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

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

    C++ 2023年5月29日
    073
  • 设置VS2017 来识别其他文件格式为C++文件

    问题:对于其他库中的文件,如.hpp, .ih 往往由于其他库的文件类型撰写风格,需要在Vs2017中能够类似于C++语法来解析这些文件,则需要如下设置: 打开”工具&…

    C++ 2023年5月29日
    042
  • 【面试攻略】C++面试-成都星合互娱

    2020-11-26-成都星合互娱 hr1.离职原因2.工作总结3.学历4.期望薪资 技术面1.自我介绍2.项目架构3.内存管理4.智能指针5.对象封装6.lua热更,热更对象的成…

    C++ 2023年5月29日
    059
  • C#与c++对应的类型

    C#与c++对应的类型 csharp;gutter:true; C#调用C++的DLL搜集整理的所有数据类型转换方式-转载</p> <pre><cod…

    C++ 2023年5月29日
    036
  • C++ register 关键字

    register 简介: register 就像是汉语和英语中的形容词(不要问为什么只有两种语言,因为小编只会这两种),在 C++ 中 register 是用来修饰变量的。 reg…

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