自定义数据类型

一种用户定义的引用[数据类型

类的基本概念

定义一个类:

class Player
{
public:	//访问权限

	int x, y;
	int speed;	//变量

	void Move(int ax, int ay)	//方法
	{
		x += ax * speed;
		y += ay * speed;
	}
};

使用类实例化一个对象:

Player player0;

访问权限

一个类的所有成员默认情况下是私有成员

  • private(私有成员)
    只有类中的函数才能访问类中的变量。
  • protected(保护成员)
  • public(公有成员)
    类之外的任何地方都可访问类中的变量

类和结构体的对比

  1. 可见度的区别:
    类中成员默认为私有成员,结构体中成员默认为公有成员

构造函数

构造函数的基本概念

  • 构造函数是一种特殊类型的方法,在每次实例化对象时都会进行

  • 构造函数可以有参数,因此可以发生重载

  • 构造函数无返回类型名字与类相同

  • 使用一个类的静态方法使用new关键字创建对象实例时构造函数将不会运行。

  • new + 构造函数会创建一个新的对象

class Entity
{
public:
	float x, y;
	Entity(float a, float b)	//构造函数
	{
		x = a;
		y = b;
	}
	void Print()
	{
		std::cout << x << "," << y << std::endl;
	}
};
int main()
{
	Entity e(5.0f, 9.0f);	//将x初始化为5.0,y初始化为9.0
	e.Print();
}

Entity为构造函数,实例化对象时每次都会初始化x,y。

删除构造函数

当希望被人只使用类而不实例化对象时,可删除构造函数。

  1. class Log
    {
    private:
       Log() {};
    };
    
  2. class Log
    {
    public:
       Log() = delete;
    };
    

构造函数初始值列表

格式:

Player(const std::string& name, float x, float y)
	:m_name(name), X(x), Y(y) {}
  • 只有成员类或基类才能显示在类或结构的初始化列表中。
  • 实现初始化列表时,要确保与成员变量声明时顺序一致。
  • 若不使用初始化列表,成员会构造两次,一次是默认构造函数,一次是相匹配的构造函数。

构造函数的分类

按参数分类:

  • 无参构造(默认构造):
Person() {}
  • 有参构造:
Person(int a) {}

按类型分类:

  • 拷贝构造:

    Person(const Person& p) {}
    

    不能用拷贝构造函数初始化匿名对象。

  • 普通构造

构造函数的调用

无参构造函数的调用:

Person p;

有参构造函数的调用:

  1. 括号调用:
Person p1(10);
Person p2(P1);
  1. 显示调用:
Person p1 = Person(10); 
Person p2 = Person(p2);

会先创建匿名对象,再将匿名对象复制给p1。

  1. 隐式转换调用:
Person p4 = 10;	//Person p4 = Person(10); 
Person p5 = p4;	//Person p5 = Person(p4); 
  • 若自行创建有参构造函数,则编译器将不再提供默认构造函数,需自行创建。
  • 若自行创建拷贝构造函数,则编译器将不再提供默认构造函数和有参构造函数,需自行创建。

调用的时机:

  1. 使用一个已经创建完毕的对象来初始化一个新对象.
Person P1(10); 
Person P2(P1); 
  1. 值传递的方式给函数参数传值。
void Function(Person p1) {}
void test02() {
	Person p;
    Function(p);
}
  1. 以值方式返回局部对象
Person Function()
{
	Person p1;
	return p1;	//会拷贝出一个新的对象,再将新的对象返回
}
void test03()
{
	Person p = Function();
}

深拷贝与浅拷贝

class Person 
{
public:
	int m_age;
	int* m_height;
	Person(int age ,int height) 
	{
		m_age = age;
		m_height = new int(height);
	}
	~Person() 
	{
		cout << "析构函数!" << endl;
		if (m_height != NULL){
			delete m_height;
		}
	}
};
  • 浅拷贝:直接进行赋值拷贝操作。

    Person(const Person& p) 
    {
    	m_age = p.m_age;
    	m_height = new int(*p.m_height);
    }
    

    浅拷贝会带来的重复释放堆区内存的问题。

  • 深拷贝:在堆区重新申请内存,再进行拷贝操作。

    Person(const Person& p) 
    {
    	m_age = p.m_age;
    	m_height = new int(*p.m_height);	
    }
    

析构函数

  • 析构函数不可以有参数,因此不可以发生重载
  • 每次销毁对象时被调用
class Entity
{
public:
	float x, y;
	~Entity()	//析构函数
	{
		x = 0;
		y = 0;
		std::cout << "destroy entity" << std::endl;
	}
};

类的对象

类对象作为类成员

  • 当类对象作为类成员时,构造时会先构造类成员,再构造自身。
  • 析构时会先析构自身,再析构类成员。

成员变量和成员函数

  • 成员变量和成员函数分开储存。
  • 只有非静态成员变量属于类的对象
  • 静态成员变量和成员函数属于类,因为在没有对象时它们依然存在。

枚举

定义一个枚举类型

enum Type :unsigned char
{
	A = 5, B, C, D	//递增1
};

枚举默认为32位整型,可在其后加冒号再加整数类型。

posted @ 2025-10-13 23:48  单身喵  阅读(6)  评论(0)    收藏  举报