C++学习记录——对象和类

本文详细介绍了C++中的类和对象概念,包括类的定义、成员类型、普通构造函数、析构函数、复制构造函数、数据成员的初始化,以及特殊成员如const、static、引用、const成员函数、static成员函数和友元函数的使用。
摘要由CSDN通过智能技术生成

目录

一、类和对象的介绍

二、类设计

1、类的定义

2、成员类型

三、成员函数

1、this 指针

2、普通构造函数

3、析构函数

4、复制构造函数

5、数据成员的初始化

四、类的特殊成员 

 1、const数据成员

2、static数据成员

3、引用成员

4、const成员函数

5、static成员函数

6、其他对象做成员

五、友元函数


一、类和对象的介绍

        类就是包含了一系列属性和行为的总和,而由类构成的,拥有类里面这一系列属性和行为的就是对象。

        例如:

#include<iostream>
using namespace std;

class Point		 
{
private: 
	int xp;
	int yp;
	
public:
	void setX(int x)
	{
		xp = x;
	}
	
	void setY(int y)
	{
		yp = y;
	}
	
	void show(void)
	{
		cout << xp <<" "<< yp;
	}
};

int main()
{
	Point a;        //创建一个Point类的对象,叫做a
	return 0;
}

        定义了一个叫做Point的类,它所含有的属性有两个坐标值, 行为有若干个函数。

二、类设计

1、类的定义

        格式:

         类的定义

                   class 类名

                   {

                   private:

                            私有成员(数据和函数)

                   protected:

                            保护成员(数据和函数)

                   public:

                            公共成员(数据和函数)

                   };

2、成员类型

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

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

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

三、成员函数

        成员函数分为:普通成员函数和特殊成员函数,特殊成员函数里有:构造函数、析构函数和复制构造函数。

        成员函数可以放在类内,也可以放在类外,在类内定义默认是内联函数,在类外定义需要在类内声明,并且定义的时候函数名前要加 类名:: 

1、this 指针

        成员函数内部有一个this指针。谁调用成员函数,this指针就指向谁。类里面所有的对象都有独立的属性成员,成员函数是共有的。this指针是类成员函数内部隐式存在的。如果数据成员的名称和参数的名称重复了,就需要显式使用this指针赋值。

//声明一个Point类的成员函数setX,Point内有叫xp的成员变量,和函数形参同名
void Point::setX(int xp)
{
	this->xp = xp;  // 指针形式
	// this指针指向了调用它的对象   ,this指针保存了对象的地址 
	// *this --- 调用的对象
	(*this).xp = xp;  // 对象形式
}

2、普通构造函数

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

        普通构造函数格式:

                            类名(形参)

                            {

                            }

        注意:1、构造函数的名称一定要和类名一致

                   2、不写返回值类型

                   3、创建对象的时候自动调用,不能手动调用

                   4、构造函数写在public权限里面。

                   5、构造函数可以有多个,支持函数重载

                   6、构造函数如果自定义就用定义的构造函数,如果没有定义就使用系统默认。

                   7、构造函数支持 形参默认值,但是形参默认是和函数重载在一起的时候小心冲突。

                   8、构造函数写在类外部,有默认参数的时候,默认参数只能有一个位置,定义或者声明,尽量将默认参数写在类内部的函数声明的位置。

#include<iostream>
using namespace std;

class Point
{
private:
	int xp;
	int yp;
public:
	Point(int x=0,int y=0)            //带形参和默认值的构造函数
	{
		xp = x;
		yp = y;
		cout << "有参构造函数执行" << endl;
	}
	
	void show(void)
	{
		cout << xp << "," << yp << endl;
	}
};

int main()
{
	Point a(1,3);
	a.show();
	
	Point b; 
	b.show();
	
	Point c(3);
	c.show();
	return 0;
}

3、析构函数

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

        格式:

                        ~类名()

                        {      

                        }

        注意:1、析构函数只能有一个                         

                   2、使用对象超出其作用域 ,自动调用对应的类的析构函数                                    

                  3、析构函数是用来清理空间(有堆区空间,则需要清理堆区空间)(不是释放成员空间),防止存在内存泄漏,产生隐患                

                   4、定义时函数名与类名相同,并且前面加上~

                   6、没有返回值类型,没有形参

                   7、析构函数可以显式调用,通常不显式调用

                   8、析构如果自定义就使用定义的析构,如果没有提供那就调用系统提供的析构函数

#include<iostream>
using namespace std;

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;
}

4、复制构造函数

        作用:对象复制,可以实现将一个对象中的数值一对一的复制到另一个空间里面去。

        格式:

                           类名(const 类名 &形参名)

                            {

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

                            }

        注意:1、复制构造函数和构造函数一样,有默认存在的,但是如果数据成员里面有指针,那就会造成多个对象的成员指向了同一片空间,就可能造成误操作。所以需要自己构建一个复制构造函数。

                   2、一个类里面复制构造函数只能有一个,和类同名,有一个参数,一般是常量引用对象。

                   3、一般复制构造不写,使用默认的,但是如果成员有指针或者堆区空间就要自定义。

                   4、普通构造函数和复制构造函数只会执行一个,具体执行哪个看形参。    

#include<iostream>
using namespace std;

class Point
{
public:
	int xp;
	int yp;
	int *zp;
	Point(int x,int y)
	{
		xp = x;
		yp = y;	
		zp = new int;
		cout << "普通构造函数" << endl;	
	}

	Point(const Point& p1) 
	{
		xp = p1.xp;
		yp = p1.yp;
		zp = new int;
		// 拷贝堆区的值
		*zp = *(p1.zp); 
		
		cout << "复制构造函数" << endl; 
	}
	
	~Point()
	{
		if(zp != NULL)
		{
			delete zp;
			zp = NULL;
			cout << "析构函数" << endl;
		}

	}
	
	void show(void)
	{
		cout << "xp:" << xp << ",yp:"  << yp << ",*zp:" << *zp << endl;
	}
};

int main()
{
	Point a(1,3);  // 调用普通构造函数
	*(a.zp) = 10;
	a.show();
	Point b(a);    // 调用复制构造函数
	*(b.zp) = 20;
	b.show();
	return 0;
}

5、数据成员的初始化

        格式:

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

                   {

                   }

        

        注意:1、初始化表达式放在构造函数后面,记得加 “:”号。

                   2、如果成员里面有const成员那么只能通过初始化的形式赋值

                   3、如果构造函数重载了,在所有的构造函数后面都要设置初始化表达式

#include<iostream>
using namespace std;

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();
	
	Point b(5);
	b.show();
	
	
	return 0;
}		
	

四、类的特殊成员 

 1、const数据成员

        数据成员前面用const限定,成员限定为只读。

        1、赋值用初始化表达式的方式进行赋值

        2、如果构造函数重载,所有的构造函数对于const成员都要进行初始化

        3const成员如果直接使用=赋值,那就可以不用初始化表达式

#include<iostream>
using namespace std;

class Point
{
private:
	int xp;
	const int yp = 100; 
	const int zp;
public:
	Point(int x,int z):xp(x),zp(z)		//初始化 
	{
//		zp = z;  // 在这里写是相当于对zp进行赋值,是错误的写法 
	}
	
	void show(void)
	{
		cout << "xp:" << xp << ",yp:" << yp << ",zp:" << zp << endl;
	}	
}; 

int main()
{
	Point a(1,3);	
	a.show();
	return 0;
}

2、static数据成员

        数据成员用static限定,成员空间创建在静态区,程序加载的时候空间就分好了。

        static数据成员在类中所有对象共享,在类外使用:数据类型 类名::静态成员名 = 值;

        static数据成员不能使用this进行操作

#include<iostream>
using namespace std;

class Point
{
private:
	int xp;
	int yp;
	static int zp;
public:
	Point(int x,int y):xp(x),yp(y){
	}
	
	void show(void)
	{
		cout << "xp:" << xp << ",yp:" << yp << ",zp:" << zp << endl;
	}	
};

int Point::zp = 100;

int main()
{
	Point a(1,2);
	a.show();
	
	Point b(3,4);
	b.show();		
	
	return 0;
}

3、引用成员

        给变量起别名,一般用在传参,引用定义的时候必须初始化

#include<iostream>
using namespace std;

class Point
{
private:
	int xp;
	int yp;
	int &zp;  //定义引用成员
	
public:
	Point(int x,int y,int &z):xp(x),yp(y),zp(z)
	{
//		xp = x;
//		yp = y;
//		zp = z;  // 错误的,因为在构造函数{}内属于赋值不属于初始化 
	}	
	
	void show(void)
	{
		cout << "xp:" << xp << ",yp:" << yp << ",zp:" << zp << endl;
	}
}; 


int main()
{
	int b = 30;
	Point a(1,3,b);
	a.show();
	
	return 0;
}

4、const成员函数

        格式:

                数据类型 函数名(形参) const

                {

                }

        const成员函数函数只能对成员进行读操作,不能对成员进行写操作。在这个函数内部只能调用其他const成员函数,不能调用非const成员函数。

#include<iostream>
using namespace std;

class Point
{
private:
	int xp;
	int yp;
public:
	Point(int x,int y):xp(x),yp(y){
	}
	
	void test1(void)
	{
		cout << "无cosnt函数" << endl;
	}
	
	void test2(void) const
	{
		cout << "有const的函数 " << endl;
	}
	
	void show(void) const
	{
//		test1();		//调用非const函数会报错 
		test2();
		cout << "xp:" << xp << ",yp:" << yp << endl;
	}	
};

int main()
{
	Point a(3,4);
	a.show();
	return 0;
}

5、static成员函数

        static成员的函数属于类内,可以使用对象进行调用,也可以使用类直接调用,调用格式:类名::函数名(实参列表);

        1、静态成员函数内只能调用静态成员函数

        2、静态成员函数中只能访问静态数据,不能访问普通数据所以静态成员函数就是为了访问静态成员设计的。

#include<iostream>
using namespace std;

class Point
{
private:
	int xp;
	int yp;
	static int zp;
public:
	Point(int x,int y):xp(x),yp(y){
	}
	
	void test1(void)
	{
		cout << "无static函数" << endl;
	}
	
	static void test2(void) 
	{
		cout << "有static的函数 " << endl;
	}
	
	static void show(void) 
	{	
		test2();
		cout << "zp:" << zp << endl;
		zp = 800;
		cout << "zp:" << zp << endl;		
	}	
};

int Point::zp = 500;

int main()
{
	Point a(3,4);
	a.show();
	Point::show();
	return 0;
}

6、其他对象做成员

        类内的成员可以是别的类构成的对象,例如:

#include<iostream>
using namespace std;

class Point
{
public:
	int xp;
	int yp;
public:
	Point(int x,int y):xp(x),yp(y){}
};

class Line
{
public:
	Point xl;
	Point yl;
public:
	Line(Point x,Point y):xl(x),yl(y){}
};

class Surface
{
public:
	Line xs;
	Line ys;
	Line zs;
public:
	Surface(Line x,Line y,Line z):xs(x),ys(y),zs(z){}
	
	void show(void)
	{
		cout << xs.xl.xp <<" "<< ys.xl.xp <<" "<< zs.xl.xp <<endl;
	}
};

int main()
{
	Point a(10,10);
	Point b(20,20);
	Point c(30,30);
	Point d(40,40);
	Point f(50,50);
	Point g(60,60);
	Line l_1(a,b);
	Line l_2(c,d);
	Line l_3(f,g);
	Surface s_1(l_1,l_2,l_3);
	s_1.show();
	
	return 0;
}

五、友元函数

        友元函数的作用就是实现用外部函数去访问类内的private成员。

        函数格式:

                   返回值类型 函数名(const 类名 &引用名)

                   {

                   }

        定义完函数后,还需要在类内声明这个函数是类的友元函数。

        声明格式:

                        friend 返回值类型 函数名(const 类名 &引用名);

#include<iostream>
using namespace std;

class Point
{
private:
	int xp;
	int yp;
public:
	Point(int x,int y):xp(x),yp(y){
	}
	// 声明printP是Point的朋友
	friend  void printP(const Point &p1);
};

// 定义一个外部函数想要访问类对象里面的私有成员xp; 
void printP(const Point &p1)
{
	cout << p1.xp << endl;
}


int main()
{
	Point a(1,3);
	printP(a);
	return 0;
}

        

        友元除了这样子使用,还可以用一个类的成员函数定义为另一个类的友元,也可以定义友元类。本文不涉及。

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值