c++笔记2

目录

1.类和对象

2.链表的封装

3.建立一个马里奥的界面

4.对象的种类


1.类和对象

        在函数外部使用class建立一个类,这是一个虚拟的不部分,当要使用这个类的时候,就在主函数中,用class定义一个新的对象,这个对象包括类中的数据以及函数。

        还要注意函数重载中,int add (int a,int b)------int add (int &a,in

int (*p)(int,int)----int (*p)(int &,int &)

#include <iostream>
#include <string>
using namespace std;
/*
类和对象
类:某一功能的数据以及算法的结合
c语言中的数据和算法是相互独立的,关联性不强
c++中的相关的数据以及结构进行封装形成结构体以及类,在没有使用到真的数据的时候,
结构体以及类都是一种虚拟的,当赋值了数据,数据才会有效,
这个数据我们就称为是对象,c++中的都是由各种类组成的,这就是面对对象

对类中的内容进行访问,要有访问修饰符
访问修饰符(3个):约束类成员的适用范围,默认的修饰方式是private
private:私有的,类成员只能类内使用
protected:保护的,类成员在类内以及子内中都可以使用
public:公共的,类成员在类内子类中都可以使用,只要是在定义类中都可以使用

*/
class PEOPLE
{
public:
	/*构造函数,编译器默认进行提供
	默认的构造函数没有返回值(不是void,是真的没有),函数名是
当前的类名,无参,函数体代码为空
	在定义对象的时候自动调用,用来初始化类成员属性,构造函数允许多个
,他们是函数重载的关系
	一旦我们手动了重构了构造函数,编译器将不再提供默认的无参的构造
	{new 在}之前进行析构},如果实在main中,就是在return 中
	*/
	PEOPLE()
	{
		p_name = "老大";

	}
	PEOPLE(string name)
	{
		p_name = name;
		p_age = 12;
		p_note = nullptr;
		p_note = new char[10];

	}
	PEOPLE(string name,int age)
	{
		p_name =name;
		p_age = age;
		p_note = nullptr;
		p_note = new char[10];

	}
	
	/*
	析构函数,编译器会默认提供
	默认的构造函数:无返回值(不是void,是真的没有),函数名是当前的类名
    ,无参,函数体代码为空 析构函数只允许有一个,并且无参数
	用来回收成员申请的额外空间,在对象声明周期结束前(对象回收前)自动调用
	PEOPLE people1("laoda")当这个创建以后,程序输出之前就会对
    这个进行析构函数的使用
	*/
	~PEOPLE()
	{
		if (p_note != 0)
		{
			delete []p_note;
			p_note = nullptr;
		}//对new创建出来的空间进行释放
		cout << "使用了析构函数" << endl;
	}
public:
	string p_name;
	char* p_note;
private:
	int p_age;
protected:
	bool p_sex;
public:
	void p_eat()
	{
		cout << p_name << " 在吃饭呢 " << endl;
	}
	void p_setage(int age)
	{
		if (age <= 40 && age >= 10)
		{
			p_age = age;
		}
		p_age = 0;
	}//可以通过设置一个岁数的范围,来防止瞎输内容,起到一个保护的作用
	int p_getage()
	{
		return p_age;
	}
	int  showage()
	{
		return p_age;
	}
};
int main01()
{
	PEOPLE people;//默认找到函数中的PEOPLE()这个,他将类中的成员都进行了赋值
	people.p_name = "江焕龙";//将class中的数据设置成public才能访问
	/*想要对私有的年龄进行更改,可以设置一个类内公共的函数people.p_setage(20), people.p_getage()*/
	people.p_setage(20);
	cout << people.p_getage() << endl;

	
	PEOPLE people1("laoda",20);//默认找到函数中的PEOPLE(string name)这个
	cout << people1.p_name << endl;
	
	
	PEOPLE * p_str = new PEOPLE("laoer", 20);
	p_str->p_name = "老三";
	delete p_str;//在主函数中开放一个指针
	p_str = nullptr;
	
	return 0;
}#include <iostream>
#include <string>
using namespace std;
/*
类和对象
类:某一功能的数据以及算法的结合
c语言中的数据和算法是相互独立的,关联性不强
c++中的相关的数据以及结构进行封装形成结构体以及类,
在没有使用到真的数据的时候,结构体以及类都是一种虚拟的
当赋值了数据,数据才会有效,这个数据我们就称为是对象,
c++中的都是由各种类组成的,这就是面对对象

对类中的内容进行访问,要有访问修饰符
访问修饰符(3个):约束类成员的适用范围,默认的修饰方式是private
private:私有的,类成员只能类内使用
protected:保护的,类成员在类内以及子内中都可以使用
public:公共的,类成员在类内子类中都可以使用,只要是在定义类中都可以使用

*/
class PEOPLE
{
public:
	/*构造函数,编译器默认进行提供
	默认的构造函数没有返回值(不是void,是真的没有),函数名是当前的类名
    ,无参,函数体代码为空
	在定义对象的时候自动调用,用来初始化类成员属性,构造函数允许多个,
    他们是函数重载的关系
	一旦我们手动了重构了构造函数,编译器将不再提供默认的无参的构造
	{new 在}之前进行析构},如果实在main中,就是在return 中
	*/
	PEOPLE()
	{
		p_name = "老大";

	}
	PEOPLE(string name)
	{
		p_name = name;
		p_age = 12;
		p_note = nullptr;
		p_note = new char[10];

	}
	PEOPLE(string name,int age)
	{
		p_name =name;
		p_age = age;
		p_note = nullptr;
		p_note = new char[10];

	}
	
	/*
	析构函数,编译器会默认提供
	默认的构造函数:无返回值(不是void,是真的没有),函数名是当前的类名
    ,无参,函数体代码为空
	析构函数只允许有一个,并且无参数
	用来回收成员申请的额外空间,在对象声明周期结束前(对象回收前)自动调用
	PEOPLE people1("laoda")当这个创建以后,程序输出之前就会对这个进行析构函数的使用
	*/
	~PEOPLE()
	{
		if (p_note != 0)
		{
			delete []p_note;
			p_note = nullptr;
		}//对new创建出来的空间进行释放
		cout << "使用了析构函数" << endl;
	}
public:
	string p_name;
	char* p_note;
private:
	int p_age;
protected:
	bool p_sex;
public:
	void p_eat()
	{
		cout << p_name << " 在吃饭呢 " << endl;
	}
	void p_setage(int age)
	{
		if (age <= 40 && age >= 10)
		{
			p_age = age;
		}
		p_age = 0;
	}//可以通过设置一个岁数的范围,来防止瞎输内容,起到一个保护的作用
	int p_getage()
	{
		return p_age;
	}
	int  showage()
	{
		return p_age;
	}
};
int main01()
{
	PEOPLE people;//默认找到函数中的PEOPLE()这个,他将类中的成员都进行了赋值
	people.p_name = "江焕龙";//将class中的数据设置成public才能访问
	/*想要对私有的年龄进行更改,可以设置一个类内公共的函数people.p_setage(20), people.p_getage()*/
	people.p_setage(20);
	cout << people.p_getage() << endl;

	
	PEOPLE people1("laoda",20);//默认找到函数中的PEOPLE(string name)这个
	cout << people1.p_name << endl;
	
	
	PEOPLE * p_str = new PEOPLE("laoer", 20);
	p_str->p_name = "老三";
	delete p_str;//在主函数中开放一个指针
	p_str = nullptr;
	
	return 0;
}

t &b)

        不是函数重载,俩个为同一个意思,但是使用函数指针的时候,可以对俩个进行分辨2.链表的封装

        设计一个单向的链表,设置一个节点的类,在定义一个链的定义,并且增加链表的很多功能,可以直接进行使用

#include<iostream>
using namespace std;

/*
 C++ 中类和结构体的区别:
 1. 默认的访问修饰符不同,结构体 public  类: private
 2. 默认的继承方式不同,结构体 public  类: private

*/
struct Node {
	int val;//节点中的内容
	Node* pNext;//定义一个指向下一节点的指针
	Node(int v) {
		val = v;
		pNext = nullptr;
	}//建立一个构造函数,对内容进行初始值赋值
};
class CMyList {//建立一个链表
private:
	Node* m_pHead;
	Node* m_pEnd;
	int  m_nSize;
public:
	CMyList() {
		m_pHead = nullptr;
		m_pEnd = nullptr;
		m_nSize = 0;
	}
	~CMyList() {
		//遍历链表回收节点空间
		Node* p_temp=nullptr;
		while (m_pHead)//当链表不为空的时候
		{
			p_temp = m_pHead;
			m_pHead = m_pHead->pNext;
			delete p_temp;
			p_temp = nullptr;
		}
		m_pHead = nullptr;
		m_pEnd = nullptr;
		m_nSize = 0;

	}
public:
	// 尾添加
	void makeback(int v)
	{
	Node* pnode	=new Node(v);
	if (m_pHead)//非空链表
	{
		m_pEnd->pNext = pnode;
		m_pEnd = pnode;
	}
	else//空链表
	{
		m_pHead = pnode;
		m_pEnd = pnode;
	}
	m_nSize++;
	}

	//头删除
	void delete_head()
	{
		if (m_pHead)//链表非空
		{
			if (m_pHead==m_pEnd)//只有一个节点
			{
				m_pHead = nullptr;
				m_pEnd = nullptr;
			}
			else//多个节点
			{
				Node* p_type = m_pHead;
				m_pHead = m_pHead->pNext;
				delete p_type;
			}
			m_nSize--;
		}
		else//链表为空
		{
			cout << "链表为空" << endl;
		}
	}
	//查看链表
	void show_list()
	{
		if (m_pHead)//链表不为空
		{
			Node* p_show = m_pHead;
			while (p_show)//当指针指向链表中的节点时候
			{
				cout << p_show->val << endl;
				p_show = p_show->pNext;
			}
		}
		else
		{
			cout << "链表为空" << endl;
		}
		
	}

	//获取长度
	int get_size()
	{
		return m_nSize;
	}

};




int main() {

	/*Node* pNode = new Node(10);
	cout << pNode->val << endl;*/
	CMyList mylist;
	mylist.makeback(1);
	mylist.makeback(2);
	mylist.makeback(3);
	mylist.makeback(4);
	mylist.makeback(5);
	mylist.show_list();
	cout << mylist.get_size() << endl;

	/*system("pause");*/
	return 0;
}

3.建立一个马里奥的界面

        建立一个奥利奥的界面,首先就需要考虑将使用什么变量,上下左右四个方向的变量,马里奥的坐标值以及行进的方向,建立一个马里奥的类,需要考虑我们需要什么一些的函数

        onrun():一直运行,不断运行这个函数,可以在这个函数中建立一个不断循环,去读取键盘中我们按下的方向键,在对这个功能进行画面上的显示

        oninit():对界面的内容进行初始化,对马里奥的图片进行链接,以及对马里奥的初始位置进行赋值对全局需要进行初始值的,都可以写在这部分的函数中

        onpaint():对界面中的内容进行重绘,以及显示界面,在结束重绘

        showmario():对mario正在行进的方向进行贴图,就是显示对应方向的马里奥的图片

        movemario():读取键盘上的方向键,移动马里奥的图片

#include<easyx.h>
#include<conio.h>
#define ESC 29 
#define DEF_UP   72
#define DEF_DOWN   80
#define DEF_LEFT   75
#define DEF_RIGHT   77
class Cmario
{
public://先把变量先设置一下
	IMAGE m_imgup;
	IMAGE m_imgdown;
	IMAGE m_imgleft;
	IMAGE m_imgright;
	int m_x;
	int m_y;
	int m_direc;
public:
	//对类中设置的变量进行初始赋值,这个赋值只是在函数未进行调用的时候进行赋值,函数中的赋值在后面写
	Cmario()
	{
		
		//创建窗口
		::initgraph(600, 600);//::意思是从全局中寻找这个函数,initgraph是系统中自带的
		//设定窗口背景颜色
		::setbkcolor(RGB(255, 255, 255));//RGB红绿蓝,显示什么颜色
		::cleardevice();//对屏幕进行清屏
		//初始化成员函数
		/*//IMAGE是一个系统中设置的初始类,不用进行初始赋值
		IMAGE m_imgup;
		IMAGE m_imgdown;
		IMAGE m_imgleft;
		IMAGE m_imgright;
		*/
		int m_x = 0;
		int m_y = 0;
		int m_direc = 0;
	}
	~Cmario()
	{
		::closegraph;//关闭窗口
	}
public:
	
	void Oninit()//逻辑意义上的初始化,与程序业务逻辑相关
	{
		//IMAGE与磁盘中的图片进行绑定关联
		::loadimage(&m_imgup, "./res/mali-up.bmp");
		::loadimage(&m_imgdown, "./res/mali-down.bmp");
		::loadimage(&m_imgleft, "./res/mali-left.bmp");
		::loadimage(&m_imgright, "./res/mali-right.bmp");
		//loadimage如果显示红线,项目属性-高级-字符集-使用多字符集
		m_x = 100;
		m_y = 100;
		m_direc = DEF_RIGHT;

		
	}
	void onrun()
	{
		//onpaint();		
		while (1)
		{
			//判断方向键是否有按下的,如果按下,获取具体的数据
			if (_kbhit())//不断扫描键盘是否有按键被按,头文件是	<conio.h>
			{
				int key = _getch();//获取具体的案件
			//如果是ESC,程序退出,break循环
				if (key == ESC)
				{
					break;
				}

				//调用人物移动的方法,将key串到人物移动的方法中
				movemario(key, 10);

				




			}
			//调用重绘
			onpaint();

			Sleep(100);


		}



	}
	void onpaint()
	{
		//批量重绘
		::BeginBatchDraw();//开始批量重绘
		//根据方向显示不同的图
		
		showmario();

		::EndBatchDraw();//结束批量绘图
	}
	void showmario()
	{
		::cleardevice();//对预留下的痕迹进行屏,也可放在onpaint()中的showmario之前
		switch (m_direc)
		{
		case(DEF_UP):
		{
			::putimage(m_x, m_y, &m_imgup);
			
		}
		break;
		case(DEF_DOWN):
		{
			::putimage(m_x, m_y, &m_imgdown);
		}
		break;
		case(DEF_LEFT):
		{
			::putimage(m_x, m_y, &m_imgleft);
		}
		break;
		case(DEF_RIGHT):
		{
			::putimage(m_x, m_y, &m_imgright);
		}
		break;
		
		}
		
	}
	void movemario(int direct, int step)//移动,步长,每次移动的距离
	{
		switch (direct)
		{
		case(DEF_UP):
		{
			if (m_y-step >=0)
			{
				m_y -= step;
			}
			else
			{
				m_y = 0;
			}
			m_direc = DEF_UP;
			break;
		}
		case(DEF_DOWN):
		{
			if (m_y + step <= 540)
			{
				m_y += step;
			}
			else
			{
				m_y =540;
			}
			m_direc = DEF_DOWN;
			break;
		}
		case(DEF_LEFT):
		{
			if (m_x - step >= 0)
			{
				m_x -= step;
			}
			else
			{
				m_x = 0;
			}
			m_direc = DEF_LEFT;
			break;
		}
		case(DEF_RIGHT):
		{
			if (m_x+step >= 0)
			{
				m_x+= step;
			}
			else
			{
				m_x = 540;
			}
			m_direc = DEF_RIGHT;
			break;
		}
		}
	}


};
int main()
{
	Cmario mario;
	mario.Oninit();
	mario.onrun();

	return 0;
}

4.对象的种类

#include<iostream>
using namespace std;

#include"标头.h"

//全局对象生命周期: 程序开始创建   -  程序退出(销毁)被回收
//作用域:整个应用程序,可跨文件使用
//CTest tst2;

//静态全局对象生命周期:程序开始创建   -  程序退出(销毁)被回收
//作用域:只能在当前文件进行使用,具有文件作用域
static CTest tst3;

//声明
extern CTest  tst2;
CTest* PTST = nullptr;
void show()
{
	static CTest  tst4;//静态局部的,第一次调用包含这个对象的函数,被调用执行(被调用多次,也不会再被创建),这种的不会被析构
	PTST = &tst4;
}
CTest play()
{
	CTest tst6(40);
	return tst6;
}
int main(){
	cout<<"-------------"<<endl;

	cout<< tst2.m_a<<endl;

	extern int aa ;

	aa = 10;


	cout<<aa<<endl;

	//tst3.m_a  =10;
	
	//CTest tst;  //栈区局部对象,遇到函数的返回或者 } 生命周期结束,自动回收

	//CTest * pTst = new CTest;

	//delete pTst;    //手动回收
	//pTst = nullptr;  //
	//
	CTest();//临时对象,生命周期仅限于当前行,遇到;结束

	cout<<"==============="<<endl;
	return 0;
}

5.对象的种类

#include <iostream>
using namespace std;
/*非静态类成员属性,属于对象,在定义对象时才存在,定义多个对象存在多分,彼此之间不影响
* 类成员函数:属于这个类,不属于对象(存在与否不依赖对象定义与否),在编译器就存在了,类成员函数只有一份
* 
* this指针:当前类对象的指针,类中非静态成员函数的参数列表中。默认编译器加的一个隐藏的参数
* 在参数列表中的
* 作用:连接对象以及类成员
* 
* 
* 静态车成员函数与普通成员函数区别:静态成员函数没有隐藏this指针参数,不能使用普通的成员(成员属性+成员函数)
* 
* 静态成员属性:不属于对象,属于类的只有一份,多个对象之间共享这个静态成员,在编译期就存在了,不依赖对象而存在
* 在类外进行初始化  类型 类名::变量名=初始化值
* 静态成员,在没有对象的时候,可以通过【类名::】调用,也可以通过对象去调用
*/
class CTEST
{
public:
	int m_a=1;
	int m_b;
	static int  m_c;//需要在外部进行初始化
	void show()//Ctest * const this)//指向对象
	{
		this->m_a;//rhis指针,跟外部的p指针其实是一个
		cout <<"this"<< this << endl;
		int a = 1;
		cout << a << endl;
	}
	void show(int b)
	{
		int m_c = b;
		cout << m_c << endl;
		cout << &(m_c) << endl;
	}
	static void get()
	{
		cout << m_c << endl;//使用静态成员属性合法,
	}
};
int CTEST::m_c = 10;//对静态变量进行初始化


int main()
{
	CTEST tst;
	CTEST* p = new CTEST();
	//cout << "p" << p << endl;
	//p->show();
	//cout << sizeof(tst) << endl;//为1   里面没有内容时候, 占位作用,表示当前对真是存在于内存当中
	//cout << sizeof(tst) << endl;//4 只有int
	//cout << &(tst.m_a) << endl;
	//cout << &(tst.m_b) << endl;
	tst.show(2);
	cout << tst.m_c << endl;
	
	

	//cout << sizeof(tst) << endl;//16.加上一个double (8),等位对齐,每个都是8,8总是16
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值