当前位置: 首页 > news >正文

C++基础部分代码

C++ OOP面对对象 this指针
C:各种各样的函数定义 struct
C++:类==》实体的抽象类型
实体(属性,行为)-》ADT(abstract data type)
OOP语言的四大特征是什么?
抽象 封装/隐藏 继承 多态
访问限定符:public公有的 private私有的 protected保护的

#include<iostream>
#include<string>
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//24+8+8=40字节
};
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);cout<<ps->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的操作 s1=s2=s3String& 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.可以任意访问对象的私有成员变量 public,privatestatic静态成员方法 =》不会生成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;//cout<<"name:"<<this->_name<<endl;//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;
}

http://www.mrgr.cn/news/28705.html

相关文章:

  • 开源AI应用安全指导框架 — OWASP AI Exchange
  • 【路径规划】WDM网络中RWA问题的教育网络规划工具(基于MILP和启发式)
  • 实用调试技巧
  • 二叉搜索树(Java实现)
  • 鸿蒙开发入门day19-使用NDK接口构建UI(二)
  • MySQL之表内容的增删改查(含oracel 9i经典测试雇佣表下载)
  • 后门账号从入门到应急响应
  • 深入解析:高性能 SSE 服务器的设计与实现
  • C++笔记---二叉搜索树
  • Scratch植物大战僵尸【机器人vs外星人版本】
  • ego-planner开源代码之数据流分析
  • 分页 101012
  • 解决Visual Studio中OpenCV链接错误:LNK2019无法解析的外部符号
  • 卷积——入门理解
  • 基于jupyter notebook + joint-spider爬虫数据的成都二手房数据可视化分析项目源代码+详细使用说明
  • CMAT:提升小型语言模型的多智能体协作调优框架
  • git笔记
  • 什么是事件驱动
  • 【C/C++】程序的构建(编译)过程概述
  • 【笔记】枚举