丰台路网站建设,wordpress4.8.3安装,南昌公路建设有限公司网站,wordpress菜单页面未找到C OOP面对对象 this指针 C:各种各样的函数定义 struct C#xff1a;类》实体的抽象类型 实体(属性#xff0c;行为)-》ADT#xff08;abstract data type) OOP语言的四大特征是什么#xff1f; 抽象 封装/隐藏 继承 多态 访问限定符#xff1a;public公有的 private私有的…C OOP面对对象 this指针 C:各种各样的函数定义 struct C类》实体的抽象类型 实体(属性行为)-》ADTabstract data type) OOP语言的四大特征是什么 抽象 封装/隐藏 继承 多态 访问限定符public公有的 private私有的 protected保护的
#includeiostream
#includestring
using namespace std;#if 0const int NAME_LEN 20;
class CGoods
{
public: //给外部提供公有的成员方法来访问私有的属性//做数据初始化void init(const char*name, double price, int amount);//打印信息void show();//给成员变量提供一个getXXX或setXXX的方法,类体内实现的方法自动初始化inlinevoid setName(char *name){ strcpy(_name, name); }void setPrice(double price){ _price price; }void setAmount(int amount){ _amount amount; }const char *getName(){ return _name; }double getPrice(){ return _price; }int getAmount(){ return _amount; }private: //属性默认私有的成员变量//对象内存大小的时候对象的内存大小和成员变量有关char _name[NAME_LEN];//20-》24double _price;//8int _amount;//4-》8//248840字节
};
void CGoods::init(const char*name, double price, int amount)
{strcpy(_name, name);_price price;_amount amount;
}
void CGoods::show()
{cout name: _name endl;cout prrice: _price endl;cout amount _amount endl;
}
int main()
{
/*
CGoods可以定义无数的对象每一个对象都有自己的成员变量但是它们共享一套成员方法show()怎么知道处理哪个对象的信息
inti(name,price,amount) 怎么知道把信息初始化给哪一个对象类的成员方法一经编译所有的方法参数都会加一个this指针接受调用该方法的对象的地址
void setName(this-char *name){};
*/CGoods good1;//类实例化了一个对象//good._price;//err//init(good1,面包, 10.1, 20);good1.init(面包, 10.1, 20);good1.show();//show(good1);good1.setAmount(200);good1.show();CGoods good2;good2.init(冰箱,1980,20);good2.show();//new 的四种用法int *p1 new int(10);int *p2 new (nothrow)(int);const int * p3 new const int (2);//定位newint statu 0;int *p4 new (statu)int(30);cout p4: *p4 endl;//c和c的开辟动态内存new | mallocint *a (int*)malloc( sizeof (int));if (a nullptr){return -1;}free(a);int *a1 (int*)malloc(sizeof(int)* 20);free(a1);int *b new int(20);delete (b);int *b1 new int[20]();delete[]b1;//专门用来引用右值类型指令上可以自动产生临时量int d 20;// const int d 20;//int d1 10;//--err//不能用一个右值引用变量来引用左值int c d; //右值引用变量本身是一个左值只能有左值引用它c 50;cout c d endl;return 0;}/*
构造函数和析构函数
OOP实现一个顺序栈
*/
class SeqStack
{
public://构造函数 SeqStack s1; SeqStack s2(20)SeqStack(int size 10) //是可以带参数的因此可以提供多个构造函数{cout this SeqStack()endl;_pstack new int[size];_top -1;_size size;}//自定义构造函数 对象的浅拷贝有问题SeqStack(const SeqStack src){cout SeqStack src endl;_pstack new int[src._size];for (int i 0; i src._size; i){_pstack[i] src._pstack[i];}_top src._top;_size src._size;}//析构函数~SeqStack() //是不带参数的所以析构函数只能有一个{cout this ~SeqStack()endl;delete[]_pstack;_pstack nullptr;}//赋值重载函数 s1 s1void operator(const SeqStack src){cout operator endl;//防止自赋值if (this src)return;//需要先释放当前对象占用的资源delete[]_pstack;_pstack new int[src._size];for (int i 0; i src._size; i){_pstack[i] src._pstack[i];}_top src._top;_size src._size;}/*void init(int size 10){_pstack new int[size];_top -1;_size size;}void release(){delete[]_pstack;_pstack nullptr;}*/void push(int val){if (full())resize();_pstack[_top] val;}void pop(){if (empty())return;--_top;}int top(){return _pstack[_top];}bool empty(){ return _top -1; }bool full(){ return _top_size - 1; }private:int *_pstack;//动态开辟数组存储顺序栈的元素int _top;//指向栈顶元素的位置int _size;//数组扩容的总大小void resize(){int *ptmp new int[_size * 2];for (int i 0; i _size; i){ptmp[i] _pstack[i];//如果拷贝的是对象对象指向了外部内存那就出问题了浅拷贝//memcopy(ptmp,_psatck,sizeof(int)*_size);}delete[]_pstack;_pstack ptmp;_size * 2;}};
SeqStack gb;//全局构造在程序运行结束析构
int main01()
{//当我在堆区开辟内存默认的析构函数不起作用就需要自己deleteSeqStack *ps new SeqStack(30);ps-push(70);ps-push(40);coutps-top()endl;delete ps;//先调用ps-~SeqStack()然后free(ps)//1.开辟内存 2.调用构造函数SeqStack s;//s.init(5);//对象变量初始化操作for (int i 0; i 15; i){s.push(rand() % 100);}while (!s.empty()){cout s.top() ;s.pop();}//s.release();//释放对象成员变量占用的外部堆内存外部资源SeqStack s2(20);//先进后出构造析构//s2.~SeqStack();//析构函数调用结束后我们说对象不存在了//s2.push(30);//堆内存的非法访问析构之后不可在访问对象的成员return 0;
}/*
this指针 》类-》很多对象 共享一套成员方法
成员方法方法的参数都会添加一个this指针构造函数定义对象时自动调用的可以重载的构造完成对象产生了
析构函数不带参数不能重载只有一个析构函数析构完成对象就不存在了16.深拷贝和浅拷贝
对象默认的拷贝构造是做内存的数据拷贝
关键是对象如果占用外部的内存那么浅拷贝就出现问题了*/
int main()
{SeqStack s;//没有提供任何构造函数的时候会为你生成默认构造函数和默认析构函数SeqStack s1(10);SeqStack s2 s1;//#1 默认拷贝构造函数做直接内存数据拷贝//SeqStack s3(s1);//#2 //s2.operator(s1);s1 s1;return 0;
}#endif
#if 0
/*
17.拷贝构造函数和赋值重载函数应用代码实践*/
class String
{
public:String(const char *str nullptr)//普通构造函数{if (str ! nullptr){m_data new char[strlen(str) 1];strcpy(this-m_data, str);}else{//置为空,让下面的拷贝构造函数不用重新判断是不是有效字符m_data new char[1];m_data \0;}}String(const String other)//拷贝构造函数{m_data new char[strlen(other.m_data)1];strcpy(m_data, other.m_data);}~String(){delete[]m_data;m_data nullptr;}//String 是为了连续的operator的操作 s1s2s3String operator (const String other)//赋值重载函数{if (this other){return *this;}m_data new char[strlen(other.m_data)1];strcpy(m_data, other.m_data);return *this;}
private:char *m_data;//用于保存字符
};int main()
{String str1;String str2(hello);String str3 world;String str4 str3;String str5(str3);str3 str4;return 0;
}
#endif
#if 0
//循环队列
class Queue
{
public:Queue(int size 5){_pQue new int[size];_front _rear 0;_size size;}//可以限制用户使用拷贝和赋值构造函数//Queue(const Queue) delete;//Queue operator(const Queue) delete;Queue(const Queue src){_size src._size;_front src._front;_rear src._rear;_pQue new int[_size];for (int i _front; i ! _rear; i (i 1) % _size){_pQue[i] src._pQue[i];}}Queue operator(const Queue src){if (this src)return *this;delete[]_pQue;_size src._size;_front src._front;_rear src._rear;_pQue new int[_size];for (int i _front; i ! _rear; i (i 1) % _size){_pQue[i] src._pQue[i];}return *this;}void push(int val)//入队操作{if (full())resize();_pQue[_rear] val;_rear (_rear 1) % _size;}void pop()//出队操作{if (empty())return;_front (_front 1) % _size;}int front()//获取队头元素{return _pQue[_front];}bool full(){ return (_rear 1) % _size _front;}bool empty(){ return _rear _front; }~Queue(){delete[]_pQue;_pQue nullptr;}
private:int *_pQue;//申请数组的空间int _front;//队头int _rear;//队尾int _size;//扩容的大小void resize(){int *ptmp new int[_size * 2];int index 0;for (int i _front; i ! _rear; i (i 1) % _size){ptmp[index] _pQue[i];}delete[]_pQue;_pQue ptmp;_front 0;_rear index;_size * 2;}
};
int main()
{Queue q1;for (int i 0; i 20; i){q1.push(rand() % 100);}while (!q1.empty()){cout q1.front() endl;q1.pop();}Queue q2 q1;q1 q2;return 0;
}
#endif#if 0/*
18.构造函数初始化列表 : 可以指定当前对象成员变量的初始化方式
CDate信息 是 CGoods商品信息的一部分 a part of ... 组合关系继承
*/
class CDate
{
public:CDate(int y, int m ,int d)//自定义了一个构造函数编译器就不会默认生成构造函数{_year y;_month m;_day d;}void show(){cout _year / _month / _day endl;}
private:int _year;int _month;int _day;
};class CGoods
{
public:CGoods(const char * n, double p, int a,int y,int m, int d):_date(y,m,d),_amount(a),_price(p)// #1 构造函数的初始化列表{// #2 当前类类型构造函数体strcpy(_name, n);//_price p;//_amount a;}void show(){cout name: _name endl;cout price: _price endl;cout amount: _amount endl;_date.show();}
private:char _name[20];double _price;int _amount;CDate _date;//成员对象};
int main()
{CGoods g1(苹果,9.8,3,2019,3,8);g1.show();return 0;
}class Test
{
public:Test(int data 10) :mb(data), ma(mb){}void show(){cout ma: ma mb: mb endl;}
private://成员变量的初始化和它们定义的顺序有关和构造函数列表中出现的先后顺序无关int ma;int mb;
};
int main()
{Test t1;t1.show();//ma:-858993460mb:10return 0;
}/*
19.掌握成员方法和区别
普通的成员方法 》编译器会添加一个this形参变量
1.属于类的作用域
2.调用该方法时需要依赖一个对象常对象是无法调用的
3.可以任意访问对象的私有成员变量 publicprivatestatic静态成员方法 》不会生成this形惨
1.属于类的作用域
2.用类名作用域来调用方法
3.可以任意访问对象的私有成员仅限于依赖对象的成员只能调用其他static静态成员const常成员方法 》const CGoods *this
1.属于类的作用域
2.调用依赖一个对象普通对象或者常对象都可以
3.可以任意访问对象的私有成员但是只能读不可写
*/
class CDate{
public:CDate(int y, int m, int d)//自定义了一个构造函数编译器就不会默认生成构造函数{_year y;_month m;_day d;}void show()const{cout _year / _month / _day endl;}
private:int _year;int _month;int _day;
};class CGoods
{
public:CGoods(const char * n, double p, int a, int y, int m, int d):_date(y, m, d), _amount(a), _price(p)// #1 构造函数的初始化列表{// #2 当前类类型构造函数体strcpy(_name, n);_count;//记录产生新对象的数量}//普通成员方法void show()//打印商品的私有信息 CGoods *this{cout name: _name endl;cout price: _price endl;cout amount: _amount endl;_date.show();}//常成员方法:只要是只读操作的成员方法一律实现成const常成员方法void show()const//const CGoods *this{cout name: _name endl;cout price: _price endl;cout amount: _amount endl;_date.show();}//静态成员方法 没有this指针的static void showCount()//打印的是所有商品共享的信息{cout 所有商品种类数量是 _count endl;//coutname:this-_nameendl;//err}
private:char _name[20];double _price;int _amount;CDate _date;//成员对象 1.分配内存 2.调用构造函数//int _count;//用来记录商品对象的总数量static int _count;//不属于对象而是属于类级别的 声明};
//static 成员变量一定要在类外进行定义并初始化
int CGoods::_count 0;
int main()
{CGoods g1(苹果1, 9.8, 3, 2019, 3, 8);g1.show();CGoods g2(苹果2, 9.8, 3, 2019, 3, 8);g2.show();CGoods g3(苹果3, 9.8, 3, 2019, 3, 8);g3.show();CGoods g4(苹果4, 9.8, 3, 2019, 3, 8);g4.show();//g2.showCount();//4CGoods::showCount();const CGoods g5(非卖品, 6.9, 4, 2022, 4, 6);g5.show();return 0;
}
#endif
/*
20.指向类成员成员变量和成员方法的指针
*/
class Test
{
public:void func(){ cout call Test::func endl;}static void static_func(){ cout Test::static_func endl; }int ma;static int mb;private:
};
int Test::mb 0;
int main()
{/*无法从“int”转换为“int Test::*int Test::*p Test::ma;*p 20;*/Test t1;Test *t2 new Test();#if 0int Test::*p Test::ma;t1.*p 20;cout t1.*p endl;//20t2-*p 30;cout t2-*p endl;//30int *p1 Test::mb;*p1 40;cout *p1 endl;//40
#endif//指向成员方法的指针/*无法从“void(__thiscall Test::*)(void)”转换为“void(__cdecl *)(void)void(*pfunc)() Test::func;(*pfunc)();*/void(Test::*pfunc)() Test::func;(t1.*pfunc)();(t2-*pfunc)();//如何定义函数指针指向类的static成员方法呢return 0;
}