gwgirl 发表于 2022-1-15 19:22

如何轻松掌握C++,理解C和C++的本质区别,学好C++

本帖最后由 gwgirl 于 2022-1-16 18:23 编辑

运行环境:
如 WIN10
涉及工具:
VS2022
编程语言:
C/C++

以下为主题内容:希望对学习C++的新手有所帮助
面向对象和面向过程最本质的三个区别:封装 继承 多态
想要学好C++没有C的基础是不可能学好C++的,C++并不会超越我们学的C的语法,用我们学的C的知识,全部都可以解决,那么C是容易学的语言,那C++还难吗?学好了C再用C++你会觉得是一种享受;
C++本身就是在C的基础上做了一些拓展,编译器帮我们生成了一些代码,当你知道C++帮我生成了哪些代码,你的C++就学完了;C++并不难学,大家不需要对C++想象的那么复杂.
????????????1.什么是封装:
把函数定义到结构体里面的写法就是封装,封装的好处就是这个函数可以很方便的访问结构体里面其他的成员;
struct Base
{
      int x;
      int y;
};
int Sub(Base* p)
{
      return p->x - p->y;
}
int main()
{
      Base T;
      Sub(&T);
}

函数写到结构体里面和外面又有什么区别呢?
普通函数使用结构体成员我们需要传参,就像下面这段代码一样,如果写入到结构体里面,
我们就不需要去手动传参,编译器会替我们把当前结构体的地址(通过寄存器ECX)传到函数当中;
struct Base
{
int x;
int y;
int Sub()
{
return x-y;
}
};
int main()
{
      Base T;
      T.Sub();
}
????????????2.什么是类:
带有函数的结构体,称为类,我们把struct 换成 class;
class Base
{
int x;
int y;
int Sub()
{
return x-y;
}
};

????????????3.什么是成员函数:
结构体里面的函数,称为成员函数;
struct Base
{
int x;
int y;                //这个是成员
int Sub()                //这个就是成员函数
{
return x-y;
}
};
???????????? this 指针的作用 ????????????????
????只要我们把函数写到结构体里面,编译器就会替我们把当前结构体的地址;
(通过寄存器ECX)传到函数当中,
????而传的这个地址,也就是指针就是this指针,this指针不占结构体宽度;
????虽然你定义的时候函数是空的,但是这个指针任然存在;
struct Base
{
int x;
int y;               
void Sub(){ }               
};

???? 用开区分哪个是参数,哪个是成员this指针不可以进行运算,不允许重新赋值
struct sclass
{
int a;
int b;
void init(int a,int b)
{
a=a; //这样写编译器分不清这两个a谁是谁,相当于自己的值赋给了自己;
this->a=a;      //我们想要把值赋给结构体的a需要用this指针告诉编译器;
this->b=b;      //this这个指针是编译器自己为我们创建的,我们不需要自己创建
}
void Print()
{
printf("%d %d",a,b);
}
};

???? 返回当前对象的首地址;
int GetAddr()
{
return *(int*)this;
}

-------------???????????????????????? 构造函数的定义 ????????????????????????-------------

构造函数的特点:希望给我的成员赋值就使用,不希望就不使用(初始化使用)
1、于类同名     构造函数会被编译器默认自动执行和调用
struct sclass
{
      int a;
      int b;
      
      sclass()
      {
                a = 1;
                b = 2;
                printf("我们没有调用这个函数他为什么执行了呢?这就是构造函数的特性\n");
      }
};

int main()
{
      sclass T;
      printf("%d %d", T.a, T.b);
      return 0;
}

2、没有返回值
3、创建对象的时候执行
4、主要用于初始化,你希望在你当前的对象创建的时候做什么事,你就把你的逻辑功能写在构造函数里
5、可以有多个(最好有一个无参数的),称为重载,其他函数也可以重载,参数可以一样但是个数一定不要一样
以下示例代码大家复制测试:
struct sclass1
{
      int a;
      int b;

      sclass1()
      {
                printf("无参数构造函数\n");
      }
      sclass1(int a,int b)
      {
                this->a = a;
                this->b = b;
                printf("有参数构造函数\n");
      }
      sclass1(int a, int b,int c)
      {
                this->a = a;
                this->b = b+c;
                printf("有参数构造函数\n");      //这三个函数之间的关系就是重载关系
      }
};

int main()
{
      sclass1 T;                //我们写无参的编译器就给我们调用无参数的
      sclass1 S(1, 2);                //我们需要有参的编译器就给我们调用有参数的
      sclass1 D(1, 2,3);      //主要我们用起来是不是很方便
      printf("%d %d\n", S.a, S.b);
      printf("%d %d\n", D.a, D.b);
      return 0;
}

6、编译器不要求必须提供,但是写了编译器就会自动调用哦个
struct Person
{
int age;
int level;
    //构造函数->给我们的成员赋值
    Person(int age,int level)
    {
    this->age=age;
    this->level=level;
    }
    //重载函数->我们在给个空函数用的时候就可以不传参数
    Person()
    {
    printf("%d %d",age,level);
    }
    void print()//成员函数
    {
      printf("%d %d",age,level);
    }
    void print(int x)//成员函数也可以重载 参数或类型不一样就可以
    {
      printf("%d %d",age,level);
    }
};
int main()
{
    Person p(1,2);//先创建对象,有构造函数的时候就必须得用,给他传参数进去
    P.print();//创建出来通过对象的方式使用成员函数
return 0;
}

-------------???????????????????????? 析构函数的定义 ????????????????????????-------------

析构函数:是给我用来做清理工作(首位的时候使用)
1、于类同名 在前面加一个波浪线 ~
2、没有返回值
3、析构函数不需要我们调用,系统替我们调用,编译器替我们生成的调用代码
4、临时变量我们不需要使用析构函数去处理
5、析构函数不允许重载,第一。没必要,第二、重载的时候第一次已经释放,那这次释放谁?
6、编译器不要求必须提供,但是写了就会自动使用,没必要的时候不要随便加;
struct Person
{
int age;
int level;
    //构造函数->给我们的成员赋值
    Person(int age,int level)
    {
    this->age=age;
    this->level=level;
    arr = (char*)malloc(1024);//这里我申请了空间需要释放
    }
    Person()//重载函数
    {
    printf("%d %d",age,level);
    }
    ~Person()//析构函数
    {
      //写个析构函数,系统就帮我们在使用完对象后释放了空间
      //不需要我们手动释放空间和调用这个析构函数
    }
   
};
int main()
{
    Person p(1,2);//先创建对象,有构造函数的时候就必须得用,给他传参数进去
    P.print();//创建出来通过对象的方式使用成员函数
return 0;
}

3.析构函数何时执行呢?
<1>/当对象在堆栈中分配(在main函数里面创建的)
当main函数执行完的时候,在return 0;执行之前,执行调用的析构函数;
int main()
{
    Person p(1,2);
    return 0;
}
<2>/当对象在全局区分配
当前的应用程序退出之前会调用析构函数;
Person p(1,2);
int main()
{
      return 0;
}

-------------???????????????????????? 继承函数的定义 ????????????????????????-------------

继承函数:定义好多个结构,但是好多成员是一样的
我们不想写就可以把他删除掉,用继承去实现
1、继承就是数据的复制
2、为什么要用继承?减少重复代码编写
3、Person1称为父类或基类
4、Teacher、student成为子类或者派生类
5、t和s可以成为对象或者实例
6、可以用父类指针指向子类对象
struct Person1
{
    int age;
    int sex;
};
struct Teacher
{
   int age;
   int sex;
    int level;
    int classID;   
};
struct student
{
    int age;
    int sex;
    int code;
    int score;
}
void test()
{
    Teacher t;
    t.age=1;
    t.sex=2;
    t.level=3;
    t.classID=4;
}
int main()
{
   test();

return 0;
}
2、为什么要用继承?减少重复代码编写
struct Person1
{
    int age;
    int sex;
};
struct Teacher:Person1//告诉他我要用他的这些成员
{
    int sex;//子类中也有这样的一个成员,继承的时候依然会把父类的这个成员继承过来,我们尽量避免出现这样的情况;
    int level;
    int classID;   
};
struct student:Person1//告诉他我要用他的这些成员
{
    int code;
    int score;
}
void test()
{
    Teacher t;
    t.age=1;
    t.sex=2;//这里我们赋值的子类成员,想要给父类的这个成员赋值怎么办呢?
    t.Person1::sex=3;//这样我们就使用了到了父类的sex;
    t.level=4;
    t.classID=5;
}
int main()
{
   test();

return 0;
}
6、可以用父类指针指向子类对象
struct Person1
{
    int age;
    int sex;
};
struct Teacher:Person1//告诉他我要用他的这些成员
{
    int level;
    int classID;   
};
void test()
{
    Teacher t;
t.age=1;
    t.sex=2;
    t.level=3;
    t.classID=4;

    teacher* pt=&t;
    printf("%x\n",pt->sex);我用指针指向这个对象t的成员
    Person1* pP=&t;
    //我也可以用父类创建的指针指向这个对象t继承过来的成员age/sex
    //不可以通过父类指针访问子类其他成员   
    printf("%x\n",pP->sex);
}
int main()
{
   test();

return 0;
}

-------------???????????????????????? 多层继承函数 ????????????????????????-------------
继承不仅仅局限于父类,下面这段代码Y继承了X,Z又继承了Y;
Z是只继承了CD呢还是AB也一起被继承过来?
struct X
{
int a;
int b;   
};
struct Y:X
{
int c;
int d;   
};
struct Z:Y
{
int e;
int f;   
};
vodi Test()
{
    Z z;
    printf("%d",sizeof(z));//Z就继承了X,Y;
}
如果父类与子类之间发生了重复定义,也是可以继承过来的,但是在使用的时候必须明确的表示出来使用的是谁的变量
struct X
{
int a;
int b;   
};
struct Y:X
{
int a;
int d;   
};
struct Z:Y
{
int e;
int f;   
};
vodi Test()
{
    Z z;
    z.X::a=1;//
    z.b=2;
    z.Y::a=3;
    z.d=4;
    z.e=5;
    z.f=6;
    printf("%d",sizeof(z));//Z就继承了X,Y;
}

-------------???????????????????????? 多重继承函数 ????????????????????????-------------
微软推荐只有一个父类但是C++支持有多个父类
如果出现同名和多层继承一样的使用
struct X
{
int a;
int b;   
};
struct Y
{
int c;
int d;   
};
struct Z:X:Y
{
int e;
int f;   
};
vodi Test()
{
    Z z;
    printf("%d",sizeof(z));//Z就继承了X,Y;
}
内存结构:
struct Z:X:Y的 顺序决定了 内存结构中谁在上面,谁在下面,这样写结构体的首地址就是a;
struct Z:Y:X的 顺序决定了 内存结构中谁在上面,谁在下面,这样写结构体的首地址就是c;
多重继承增加了程序的复杂度,不建议使用;

?????????????????????????????????????? 如何在堆中创建对象 ??????????????????????????????????????
1.我们可以在什么地方创建对象
<1>全局变量区
Person p;
<2>栈:什么时候调用对象,什么时候分配空间,函数调用完毕之后,这个空间就没有了
void Max()
{
Person p;
}
<3>堆: new delete
在堆中创建对象:
Person* p=new person();//C++我们申请空间使用NEW这个关键词
释放对象占用的内存:
delete p;
????malloc(N)我们在C语言中想使用空间就可以通过malloc函数,申请的空间就是在堆中分配的

一些书上堆new 和 delete 的描述都很模糊,下面我们看一下new到底做了那些事情;
class person
{
      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");
      }
};

int main()
{
      //在堆中创建对象
      person* p = new person(1, 2);
//new 除了创建堆空间以外,还要调用构造函数 ,相当于malloc+构造函数
//new 最终要调用的是HeadAlloc Windows系统函数(不是我们的EXE内部的函数)
      //释放对象占用的内存空间
      delete p;\
//delete 除了释放堆空间以外,还要调用析构函数,相当于free+析构函数
      return 0;
}

如果使用的是数组,那就不能使用new了,而需要使用new[ ] 和delete[ ]

我们分别用C和C++两种方式,在堆中申请一个int类型的数组:
<1>
int* p = (int*)malloc(sizeof(int)*10);                        free(p);
int* p = new int;                                                delete[ ]p;
<2>
int* p = (Person*)malloc(sizeof(Person)*10);      free(p);
Person* p = new Person;                                 delete[ ]p;
?????????????????????    后续继续把虚函数等等都给大家发出来希望对大家有所帮助????????    ?????????????????????



gwgirl 发表于 2022-1-19 17:06

感谢大家看完了还给留个积分经验什么的!{:5_124:}

hdukhw 发表于 2022-1-22 08:41

感谢楼主

张三 发表于 2022-1-22 12:45

学习了!

缓慢仙人掌 发表于 2022-1-22 22:43

不知道来晚了没有

动听有小蝴蝶 发表于 2022-1-22 22:48

谢谢分享

活泼保卫蜻蜓 发表于 2022-1-23 12:19

谢谢分享

ALNHRvIO6270 发表于 2022-1-23 18:18

感谢楼主

Rrquk3 发表于 2022-1-24 00:35

来了来了,顶一顶,好东西!

CLybc73 发表于 2022-1-24 00:53

谢谢分享
页: [1] 2 3 4 5 6 7 8
查看完整版本: 如何轻松掌握C++,理解C和C++的本质区别,学好C++