C++ 类

本文详细介绍了C++中的类设计,包括类的定义、成员变量和函数权限,以及特殊函数如构造函数、析构函数和复制构造函数的用法。还讨论了this指针、数据成员的初始化和注意事项。
摘要由CSDN通过智能技术生成

C++类

1、类设计

1.1 类定义

格式:

class 类名 {

private:

私有的成员变量和成员函数

protected:

保护的成员变量和成员函数

public:

保护的成员变量和成员函数

};

例:

//狗类:--属性 --种类、体型、毛色、年龄
	   --行为 --叫 -- 函数

class Dog {
private:     //属性
	string dogType;
	string size;
	string color;
	int age;
	
public:
	void bark(void) {     //行为
		cout<< "旺旺旺" << endl;
	}
};

int main() {
	Dog d;
	d.bark();
	return 0;
}

1.2 权限

public:

所有的成员属性和成员函数可以在类内访问,也可以在外部通过创建对象进行调用

private:

所有的成员属性和成员函数可以在类内访问,不能在外部访问,一般设计接口函数 get set函数

protected:

所有的成员属性和成员函数可以在类内访问,也可以在它的子类中访问

例:public 属性和函数

#include<iostream>
using namespace std;

class Dog
{
public:
	string brand;
	string size;
	string color;
	int age;
public:	
	void bark(void)
	{
		cout << "汪汪汪"  << endl;
	}
};
int main()
{
	Dog a;
	a.brand = "jiji";  		//外部可以访问操作成员属性
	cout << a.brand << endl;
	 
	return 0;
}

例:private 属性和函数

#include<iostream>
using namespace std;

class Dog
{
private:
	string brand;
	string size;
	string color;
	int age;
public:	
	void bark(void)
	{
		cout << "汪汪汪"  << endl;
	}	
	void setBrand(string b)
	{
		brand = b;
	}	
	string getBrand(void)
	{
		return bran
	}
};
int main()
{
	Dog a;
	a.setBrand("xiaohuagou");   //成员属性被设置为私有 只能通过设置的函数借口对属性进行操作
	cout << a.getBrand() << endl; 
	 
	return 0;
}

例:protected属性和成员,涉及到继承 – 继承public 和 protected成员

#include<iostream>

using namespace std;
class Dog
{
protected:
	string brand;
	string size;
	string color;
	int age;
public:	
	void bark(void)
	{
		cout << "汪汪汪"  << endl;
	}	
	void setBrand(string b)
	{
		brand = b;
	}	
	string getBrand(void)
	{
		return brand;
	}
};
// 继承 
class B:public Dog
{
public:
	void test()
	{
		cout << brand << endl;
	}
};
int main()
{
	Dog a;
	a.setBrand("xiaohuagou");
	cout << a.getBrand() << endl; 

	B t;
	t.setBrand("xiaobaicai");
	t.test(); 
	 
	return 0;
}

ps:一般设计类的时候属性设计成私有的-private,函数设计成共有的-public。

2、成员函数

2.1 成员函数介绍

分类:普通成员函数、构造函数、析构函数、复制构造函数

定义位置:

  • 类内定义:默认是内联函数
  • 类外定义:类内声明,类外定义 — 推荐的写法
  • 类外定义: 函数名前要加 类名::

2.2 this指针

  • 成员函数内部有一个this指针。谁调用成员函数,this指针就指向谁。
  • 类里面所有的对象都有独立的属性成员,成员函数是共有的。
  • this指针是类成员函数内部隐式存在的。
  • 如果数据成员的名称和参数的名称重复了,就需要显式使用this指针赋值。
void Point::setX(int xp)
{
	// this->xp = xp;  // 指针形式
	// this指针指向了调用它的对象   ,this指针保存了对象的地址 
	// *this --- 调用的对象
	(*this).xp = xp;  // 对象形式
}

2.3 特殊函数——普通构造函数

作用:构造函数是在创建对象的时候自动调用,一般完成对象的赋值或者初始化操作。

普通构造函数

类名(形参)

{

}

ps:

  • 构造函数的名称一定要和类名一致
  • 不写返回值类型
  • 创建对象的时候自动调用,不能手动调用
  • 构造函数写在public权限里面。
  • 构造函数可以有多个,支持函数重载
  • 构造函数如果自定义就用定义的构造函数,如果没有定义就使用系统默认。
  • 构造函数支持 形参默认值,但是形参默认是和函数重载在一起的时候小心冲突。
  • 构造函数写在类外部,有默认参数的时候,默认参数只能有一个位置,定义或者声明,尽量将默认参数写在类内部的函数声明的位置。
class Point
{
private:
	int xp;
	int yp;
public:
//	Point()
//	{
//		cout << "无参构造函数执行" << endl;
//	}
	Point(int x,int y)    //有参构造函数
	{
		xp = x;
		yp = y;
		cout << "有参构造函数执行" << endl;
	}
	
	void show(void)
	{
		cout << xp << "," << yp << endl;
	}
	
	
};
int main()
{
	Point a(1,3);
	a.show(); // 输出 -- 1,3
	
	return 0;
}

2.4 特殊构造函数之析构函数

析构函数:对象销毁的时候自动调用的函数,一般用来清除数据成员的空间。

格式:

~类名()

{

}

ps:

  • 析构函数只能有一个
  • 使用对象超出其作用域 ,自动调用对应的类的析构函数
  • 析构函数是用来清理空间(有堆区空间,则需要清理堆区空间)(不是释放成员空间)
  • 为了安全,防止存在隐患—防止内存泄漏
  • 函数名与类名相同,并且前面加上~
  • 没有返回值类型,没有形参
  • 析构函数可以显式调用,通常不显式调用 – 不推荐
  • 析构如果自定义就使用定义的析构,如果没有提供那就调用系统提供的析构函数
class Point
{
private:
	int xp;
	int yp;
	int *zp;
public:
	// 创造对象的时候自动调用 
	Point(int x,int y)
	{
		xp = x;
		yp = y;
		zp = new int;
		cout << "调用有参构造函数" << endl;	
	} 
	
	// 对象销毁的自动调用,析构函数 
	~Point()
	{
		if(zp != NULL)
		{
			delete zp;
			zp = NULL;
			cout << "析构函数" << endl;
		}
	} 
};
int main()
{
	Point a(1,3);
	a.~Point(); //不建议手动调用  容易造成空间重复释放
	
	return 0;
}

2.5 特殊构造函数之复制构造函数

作用:对象复制。

默认构造函数,可以实现将一个对象中的数值一对一的复制到另一个空间里面去

复制构造函数格式:

类名(const 类名 &形参名)

{

// 自己实现对成员数据的一一赋值

}

注意:

  • 一个类里面复制构造函数只能有一个
  • 和类同名,有一个参数,一般是常量引用对象
  • 一般复制构造不写,使用默认的,但是如果成员有指针或者堆区空间就要自定义
  • 普通构造函数和复制构造函数只会执行一个,具体看参数怎么
class Point
{
public:
	int xp;
	int yp;
	Point(int x,int y)
	{
		xp = x;
		yp = y;		
	}
	
	void show(void)
	{
		cout << "xp:" << xp << ",yp:"  << yp << endl;
		}
};
int main()
{
	Point a(1,3);
	
	Point b = a;

	
	a.show(); //xp:1,yp:3
	b.show(); //xp:1,yp:3
	
	
	return 0;
}

但是如果数据成员里面有指针,那就会造成多个对象的成员指向了同一片空间,就可能造成误操作。

解决办法:自定义赋值构造函数

class Point
{
public:
	int xp;
	int yp;
    int *zp;
	Point(int x,int y)
	{
		xp = x;
		yp = y;		
	}
    
    Point(const Point& p1) 
	{
		xp = p1.xp;
		yp = p1.yp;
		zp = new int;
		// 拷贝堆区的值
		*zp = *(p1.zp); 
		
		cout << "复制构造函数" << endl; 
	}
	
	void show(void)
	{
		cout << "xp:" << xp << ",yp:"  << yp << ",*zp" << *zp << endl;
	}
};
int main()
{
	Point a(1,3);
	a.zp = new int;	
	*(a.zp) = 100;	
	
	// Point b = a;
	 Point b(a);
	
	a.show(); //xp:1,yp:3,zp:100
	b.show(); //xp:1,yp:3,zp:100
	
	*(b.zp) = 200;
	
	a.show(); //xp:1,yp:3,zp:100
	b.show(); //xp:1,yp:3,zp:200
	
	return 0;
}

2.6 数据成员的初始化

初始化表达式 (非静态成员)

类名(形参):成员名(参数名),成员名(参数名)

{

}

ps:

  • 初始化表达式放在构造函数
  • 如果成员里面有const成员那么只能通过初始化的形式赋值
  • 如果构造函数重载了,在所有的构造函数后面都要设置初始化表达式
class Point
{
public:
	int xp;
	int yp;	
	const int zp;
	Point(int x,int y,int z):xp(x),yp(y),zp(z)
	{
		
	}	
	Point(int z):zp(z)
	{
		xp = 5;
		yp = 10;
	}
	
	void show(void)
	{
		cout << "xp:" << xp << ",yp:"  << yp  << ",zp" << zp << endl;
	}
};
int main()
{
	Point a(1,3,5);
	a.show(); //xp:1,yp:3,zp:5
	
	Point b(5);
	b.show(); //xp:5,yp:10,zp:5
	
	
	return 0;
}		
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值