十、C++中的类 class与struct的区别

面向对象程序设计,需要诸如类和对象这样的概念。

C++支持面向过程、基于对象、面向对象、泛型编程四种

C语言不支持面向对象编程

类是一种将数据和函数组织在一起的方式。

一个函数参数过多,代码不好维护,可创建一个类,一次性包含所有想要的数据,最终作为一个类型。

类必须是唯一的类型名,因为类基本上就是我们创建一个新的变量类型,类使用{}括起来,但是结尾还有一个“;”符号。

由类 类型制成的变量叫做对象,新创建对象的过程叫做实例化。

【结构体struct和类class区别在于权限,class默认private,struct默认public】

访问控制:当创建一个类是,可以指定类中属性的可见性,默认情况下,类中的成员的访问控制都是私有的,只有类内部的函数才能访问这些变量。如果想要在main函数中访问这些变量,类需要被定义为共有的,共有表示被允许在类外访问这些变量。

类的创建与访问:

#include <iostream>
#define LOG(x) std::cout << x << std::endl

class Player
{
public:
	int x, y;
	int speed = 2;
};
int main()
{
	Player player;//使用类,前面是类名,后面随意,类型为Player的player变量
	player.x = 5;
	std::cin.get();
}

类的移动,编写函数改变X,Y变量,

#include <iostream>
#define LOG(x) std::cout << x << std::endl

class Player
{
public:
	int x, y;
	int speed = 2;
};

void move(Player& player, int xa, int ya)//接收要移动的Player,引用传递
{
	player.x += xa * player.speed;
	player.y += ya * player.speed;
}

int main()
{
	Player player;
	move(player, 1, -1);
	std::cin.get();
}

类中可以包含函数,可以移动move函数到类内,类内的函数被称作method(方法),函数在类内,访问函数变量时就不需要再传player对象。

#include <iostream>
#define LOG(x) std::cout << x << std::endl

class Player
{
public:
	int x, y;
	int speed = 2;

	void move( int xa, int ya)//接收要移动的Player,引用传递
	{
		x += xa * speed;
		y += ya * speed;
	}
};

int main()
{
	Player player;
	player.move(1, -1);
	std::cin.get();
}

类就是能使我们对变量进行组织,变成一个类型。这些变量还可以添加函数。

18

在C++中结构体struct与类class的区别:

让一个类的成员在默认情况下是私有的,编译时会得到错误。报错类里的某一个变量是无法访问的,因为按照预设值,这个变量是私有,只有类中的方法(method,其实是类中定义的函数)才能访问类中的变量。所以要添加public。

默认情况下,类是私有的(如果没有指定任何类型的可见修饰符,或者没有指定任何内容)。

而struct默认是共有的。如果要将结构体变为私有,要明确写出private。作用上没有太大区别,但是在代码实际使用时确实有所不同。结构体存在的原因,保持与C之间的兼容性,C中没有类,只有结构体。

谈论plain old data(pod)时,尽可能使用struct,只是在谈论某种结构,仅仅代表变量,如向量。

//想定义一个结构,将两个浮点数放在一起,比如Vec2
struct Vec2//Vec2结构只是浮点数的表现形式
{
	float x, y;//仅仅将两个变量按字面意思组合起来

	void Add(const Vec2& other)//添加方法,接收另一个Vec2
	{
		x += other.x;
		y += other.y;
	}
};

结构体最好不要使用继承。如果要用一个完整的类层次或某种继承层次,建议使用类。因为继承又增加了另一层复杂性,结构体建议仅仅是数据结构体。

建议struct仅仅存储数据,涉及到别的建议使用类。

19

如何创建一个类

创建Log类

Log是我们管理Log信息的一种方式,是把我们想要的信息打印到控制台上,这在调试程序时很有用。在我们的程序应用中如果你想知道发生了什么,只需要把事物的状态打印到控制台上就可以。控制台就像是信息转储的地方,可以用来显示发生了什么,这是几乎可以保证程序正确运行的方式,在游戏应用中我们要显示一个图像或者其他东西,这有时候会出现问题,然而控制台是内置在操作系统中的程序,所以它几乎总是正常工作的,。Log类可以根据需求写的很简单,也同样可以很复杂,但是它对开发和调试很重要。

日志系统不止可以把信息打印到控制台,也可以打印不同的颜色,或者把日志输出到文件、网络等。

最简单的log类,仅仅实现向控制台发送文本,可以控制发送给控制台log信息量的级别,最开始有三个级别,错误error、警告warning和信息message(或者叫跟踪trace)三个。

        把日志级别设置为warning时,只有warning和error级别的log信息可以打印出来,message(trace)级别的不行。当只需要查看程序的警告与报错信息时可以这样设置。

①创建一个log类

相像log类是如何工作的,创建一个类或者设计一个API的方式是研究它的使用情况。

class Log

{

};

②进入main函数,开始编写我们如何使用log类

实例化一个类、需要指定一个log级别作为它的实参。先跳过这一步;//设置一个log级别,因此要有一个SetLevel方法,参数为LogLevelWarning指warning级别。只有warning和error级别的log信息可以打印出来,message(trace)级别的不行。//打印一个warning信息,log.Warn("Hello!")...

以上知道了log类需要那些功能,现在去定义中实现。

③编写log类

public,显示SetLevel函数。用一个整数代表log级别。warn函数有一个字符串指针,是我们要打印的消息,const char* 是字符串的意思。声明LogLevelWarning存在,声明log level变量。创建私有变量成员代表设置的log级别,整数型的变量名称m_LogLevel,m前缀表示是私有类的成员变量.

设置2为message(trace)级别,1代表warning,0代表error。创建变量,他们的值代表我们要表示的东西。把LogLevelWarning设置为共有变量。

public方法放在一部分,public变量放在另一部分,public static变量在另一部分。设置的值都是常数,所以要写const int 然后设置LogLevelWarning的值,

#include <iostream>
#define LOG(x) std::cout << x << std::endl

class Log
{
public:
	const int LogLevelError = 0;
	const int LogLevelWarning = 1;
	const int LogLevelInfo = 2;
private:
	int m_LogLevel = LogLevelInfo;//默认情况下所有东西都需要打印
public:
	void SetLevel(int level)
	{
		if (m_LogLevel >= LogLevelError)
			m_LogLevel = level;//函数中变量的引用
	}

	void Error(const char* message)
	{
		if (m_LogLevel >= LogLevelError)
			std::cout << "[ERROR]:" << message << std::endl;
	}

	void Info(const char* message)
	{
		if (m_LogLevel >= LogLevelInfo)
			std::cout << "[INFO]:" << message << std::endl;
	}

	void Warn(const char* message)
	{
		if (m_LogLevel >= LogLevelWarning)
			std::cout << "[WARNING]:" << message << std::endl;
	}
};



int main()
{
	Log log;//首先进行实例化
	log.SetLevel(log.LogLevelWarning);//设置警告等级,警告或错误才会被打印
	log.Warn("Hello");//设置Log警告信息“Hello”
	log.Error("Hello"); 
	log.Info("Hello");
	std::cin.get();
}

 由于log级别被设置为warning,所以info消息没有被打印。

如果不设置log级别,默认会设为info

#include <iostream>
#define LOG(x) std::cout << x << std::endl

class Log
{
public:
	const int LogLevelError = 0;
	const int LogLevelWarning = 1;
	const int LogLevelInfo = 2;
private:
	int m_LogLevel = LogLevelInfo;//默认情况下所有东西都需要打印
public:
	void SetLevel(int level)
	{
		if (m_LogLevel >= LogLevelError)
			m_LogLevel = level;//函数中变量的引用
	}

	void Error(const char* message)
	{
		if (m_LogLevel >= LogLevelError)
			std::cout << "[ERROR]:" << message << std::endl;
	}

	void Info(const char* message)
	{
		if (m_LogLevel >= LogLevelInfo)
			std::cout << "[INFO]:" << message << std::endl;
	}

	void Warn(const char* message)
	{
		if (m_LogLevel >= LogLevelWarning)
			std::cout << "[WARNING]:" << message << std::endl;
	}
};



int main()
{
	Log log;//首先进行实例化
	//log.SetLevel(log.LogLevelWarning);//设置警告等级,警告或错误才会被打印
	log.Warn("Hello");//设置Log警告信息“Hello”
	log.Error("Hello"); 
	log.Info("Hello");
	std::cin.get();
}

 运行代码,三种消息都会被打印出来。

20


版权声明:本文为m0_66179815原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。