C++——面向对象(一)——默认的构造函数(1)

来源:互联网 发布:mysql错误1054 编辑:程序博客网 时间:2024/05/18 11:27

C++——类和对象

面向过程:C

面向对象:C++


面向对象的设计模式,如图:

  在现实世界中,存在很多实体,都有自己的属性和行为,比如猫,狗,人,等等,他们都属于动物,人的属性为姓名,年龄和性别,行为吃,睡,玩,将这些属性和行为抽象出来形成抽象数据类型,那么这个抽象数据类型在计算机的世界中就对应着类,计算机的类有自己的成员变量和成员函数,将这个类实例化为对象,这个对象就对应着现实世界中的实体,一个类可以实例化出多个对象,成员变量是私有的,成员函数是公有的,就像现实世界你的名字,年龄和性别是私有的,但是行为吃,睡,玩,是人类所共有的。


#include <iostream>using namespace std;typedef struct _Stud//学生类型的结构体{char *pname;int age;float score;}Stud;void init(Stud *pstud, char *name, int age, float score)//学生的结构体变量的指针,初始化{pstud ->pname= new char[strlen(name) + 1];//开辟动态内存strcpy(pstud->pname, name);pstud ->age = age;pstud ->score  = score;}void show(Stud *pstud)//打印函数{cout<<"name: "<<pstud->pname <<endl;cout<<"age: "<<pstud->age <<endl;cout<<"sccore: "<<pstud->score <<endl;}void release(Stud *pstud)//释放内存{delete []pstud->pname;pstud->pname = NULL;}int main(){Stud stud;init(&stud, "zhang", 20, 78.5);show(&stud);release(&stud);return 0;}

打印结果:

不能让指针指向其他的,也就是不能修改指针,所以给结构体前面加  const  , 如图 :

通过函数指针间接调用函数,

面试问题:通过指向这个函数的指针调用函数 和 通过函数名调用函数有什么区别?

函数指针的使用:通过函数指针回掉函数

struct 和 class 区别:

1.struct 默认共有,class 默认私有

2.C++里面可以定义空的结构体,占1个字节,

   C里面 不可以定义空的结构体



面向对象思想的三大特征:  封装 ,继承,多态,

封装:

封装与隐藏

访问限定符:

1.public: 共有的, 任意位置都能访问

2.protected:保护的,体现在继承派生,子类可以访问父类的保护成员

3.private: 私有的,,只有类中能够访问,也就是只有在自己才能访问,谁都不能访问


#include <iostream>using namespace std;class CGoods//类名以大写C开头{public://成员方法   _thiscallvoid Register(char *name, int amount, float price);void Show();//自动被编译器处理成Inline函数void SetName(char *name){strcpy(_name,name);}void SetAmount(int amount){_amount = amount;}void SetPrice(float price){_price = price;}void GetName(char *name){strcpy(_name,name);}//char *GetName(){return _name};//error,修改了私有成员变量的值int GetAmount(){return _amount;}float GetPrice(){return _price;}private:char _name[20];int _amount;float _price;};//类外有标准的函数栈帧的开辟void CGoods::Register(char *name, int amount, float price)//必须在函数名之前加上类名{strcpy(_name,name);_amount = amount;_price = price;}void CGoods::Show(){cout<<"name:"<<_name<<endl;cout<<"amount:"<<_amount<<endl;cout<<"price:"<<_price<<endl;}int main(){CGoods good;good.Register("mianbao",20,22.5);good.Show();return 0;}

运行结果:



从这份代码可以看出,用同一个类类型所定义的不同对象,每个人都有一份成员变量,但是它们共享类里面的成员方法

把数据带入栈的方式,Push操作 和 _fastcall,快速调用约定,省略了压栈的过程,直接通过寄存器带进去的,

move移值,lea移地址,


从反汇编可以看出,good1.Register("shangpin1", 200, 8.5) 其实底层是传了4个值,good1.Show() 传了一个值,通过寄存器带入的,比传统压栈速度快,在汇编上实际上是 CGoods::good1.Register(&good1, "shangpin1", 200, 8.5),也就是说除了表面上的三个参数,还要把被调用对象的地址传进去,再汇编上和 C 一样,

   调用的时候加了实参,那么形参也得有,形参里面都多了  CGoods *this ,为了防止指针指向另外的对象,指针前面要加const,即CGoods const *this,

我们把接收对象地址的指针叫做 this 指针,this 指针指向调用该成员方法的对象,关键字不能定义变量名,this 指针在编译的时候会自动添加,

   编译的时候编译器做了3件事,第一,在调用该成员对象的方法中加了CGoods const *this,第二,在调用的对象中加入了该对象的地址,第三,在调用该成员对象的方法中加入了this ->amounnt ,tihs->price,strcpy(this->name,name),

 将name改为指针,
由于,_pname指向堆上的内存,在main函数推出后不能销毁它所占用的资源,所以添加一个Release函数来释放堆上的这块内存,

C++采用系统调用函数 构造函数 和 析构函数 来代替Register 和 Release 函数的功能

构造函数的特点,没有返回值,名字和类名一样,构造函数可以重载,
构造函数:可以带参数
CGoods

析构函数:不能带参数
~CGoods
1.分配对象内存空间
2.调用对象的构造函数

 C语言:结构体 -》变量 : 分配内存
C++:类 -》 对象
1.分配对象内存空间
  2.调用对象的构造函数
说明构造函数和析构函数也有 this 指针,

return会产生很多的汇编语句,包括栈帧是怎么回退的,是通过寄存器带回的还是,
构造函数不能自己手动调,永远是编译器自己调,构造函数是产生对象的,

调用了析构函数之后就不能再调用Show函数,因为占用的内存已经被释放了,被置为NULL了,

顺序栈的实现:
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<iostream>using namespace std;#pragma warning(disable:4996)class CStack{public:CStack(){mtop = 0;}~CStack(){}CStack(const CStack& rhs){for (int i = 0; i < rhs.mtop; ++i){mval[i] = rhs.mval[i];}mtop = rhs.mtop;}void operator=(const CStack& rhs){if (this == &rhs){return;}for (int i = 0; i < rhs.mtop; ++i){mval[i] = rhs.mval[i];}mtop = rhs.mtop;}void Push(int data){if (mtop < MAXSIZE){mval[mtop++] = data;}}int Pop(){if (mtop == 0)throw("Stack Empty!");return mval[--mtop];}int Top(){if (mtop == 0)throw("Stack Empty!");return mval[mtop-1];}void Show(){for (int i = 0; i < mtop; ++i){cout << mval[i] << " ";}cout << endl;}private:enum{ MAXSIZE = 20 };int mval[MAXSIZE];int mtop;};int main(){CStack st;for (int i = 0; i < 10; ++i){st.Push(i+1);}st.Show();int a = st.Pop();st.Show();cout << a << endl;return 0;}

运行结果:




阅读全文
0 0