类和对象 【2】

一、对象初始化列表

类中如果有一个其他类的对象,而其他类没有无参构造函数,无法初始化

该类的对象,需要对象初始化列表对其进行初始化

注意点:

1、对象初始化列表的优先级高于当前对象的构造函数进行

2、对象的构造和在对象初始化列表中的位置无关,和在类中声明的顺序有关

3、const常量必须在初始化列表中初始化

下面举个圆与点的列子:

class Point
{
public:
	Point(int x, int y)
	{
		m_x = x;
		m_y = y;

		printf ("Point 构造函数:%d, %d\n", m_x, m_y);
	}
	~Point()
	{
		printf ("Point 析构函数:%d, %d\n", m_x, m_y);
	}

	void print()
	{
		printf ("x = %d, y = %d\n", m_x, m_y);
	}
private:
	int m_x;
	int m_y;
};

class Circle
{
public:
	
	Circle(int r, int x, int y): c1(4,5), c(x, y), m_r(r), a(r)
	{
		// m_r = r;
		printf ("Circle 构造函数\n");
	}
	~Circle()
	{
		printf ("Circle 析构函数\n");
	}

	void print()
	{
		printf ("r = %d\n", m_r);
		c.print();
	}
private:
	int m_r;   
	Point c1;
	Point c;
	
	const int a;   // const 常量 
};


析构的顺序和构造的顺序相反

构造函数中不要调用其他构造函数,无法完成初始化操作


二、对象的动态创建和释放

1、在C语言中使用的是malloc和free实现在堆上空间的分配和释放

在C++中使用的是new和delete实现在堆上空间的分配和释放

2、区别:

malloc和free是库函数,是C语言标准库提供的函数,不是C语言的一部分

new和delete是C++运算符,C++语法的一部分,new和delete效率比malloc和free高


基础数据类型空间分配

// C++ new delete
// new :   new 数据类型
int *p2 = new int; // 分配一个整型空间
*p2 = 12;
cout << *p2 << endl;
delete p2;   // 释放空间

// new 的时候可以直接初始化
// new 数据类型(初始值)
、int *p3 = new int(5);
cout << *p3 << endl;
delete p3;


动态分配数组

void func5_2()
{
	// C:  分配数组  int  a[100];
	int *p = (int *)malloc(sizeof(int)/sizeof(char)*100);
	// 释放
	free(p);


	// C++:
	// new :  new 数据类型[个数]
	// new 分配数组的时候是不能进行初始化的
	int *p1 = new int[100];

	// 释放数组:delete []
	// 不加 []  会造成内存泄露
	delete [] p1;
}

动态分配对象

void func5_3()
{
	// C语言仅仅是在堆上 分配了 一个对象的空间
	Test5_1 *p1 = (Test5_1*)malloc(sizeof(Test5_1)/sizeof(char));
	free (p1);

	// C++
	// new 对象的时候  会调用对象的构造函数对对象进行初始化
	Test5_1 *p2 = new Test5_1;

	// delete 的时候 会调用对象的析构函数 回收对象的资源
	delete p2;


	Test5_1 *p3 = new Test5_1(10);   // 有参构造
	delete p3;
}

三、类中的静态成员

1、静态成员函数只能使用静态成员变量

2、静态成员变量是类的成员,不是对象的成员,属于类,所有类的对象所共享的参数

3、静态成员变量必须重新定义并初始化

静态成员变量使用方式

1、通过对象使用  

2、通过类名::去使用

	t2.m_sa = 300;
	cout << "Test6_1::m_sa = " << Test6_1::m_sa << endl;

	Test6_1::m_sa = 89;
	cout << "t2.m_sa = " << t2.m_sa << endl;


四、对象模型

class Test7_1
{
public:
	Test7_1(int a, int b)
	{
		m_a = a;
		m_b = b;
	}

	// 类的普通成员函数内都有一个隐藏的指针 this,  该指针指向当前操作的对象
	void print ()  // ===> void print (Test7_1 *const this) 
	{
		printf ("a = %d, b = %d\n", this->m_a, this->m_b);
	}

	// 静态成员函数内部没有 this 指针,所以无法使用类的普通成员变量
	static void printA ()
	{
		printf ("m_sa = %d\n", m_sa);
	}
private:
	int m_a;
	int m_b;
	static int m_sa;
};

int Test7_1::m_sa = 10;


const在类的内部使用

class Test7_2
{
public:
	Test7_2(int a, int b)
	{
		this->a = a;
		this->b = b;
	}

	void  print () const  // void print (const Test7_1 *const this) //函数()后的const表示,隐式指向的对象不可修改
	{
		printf ("a = %d, b = %d\n", this->a, this->b);
	}
public:
	int a;
	int b;
};

// 类的内部成员函数和全局函数 实现同样的功能  有哪些不一样的地方  
// 全局函数比 类的内部函数 多了一个参数
void print(Test7_2 &obj)   // Test7_2 * const this
{
	printf ("a = %d, b = %d\n", obj.a, obj.b);
}

int main7_2()
{
	Test7_2 t(1,2);
	t.print();


	return 0;
}

五、友元函数和友元类

要在类的外部使用类中的私有成员,使用友元函数,让全局函数操作类的私有成员变量

友元函数的声明:在函数原型前加上关键字friend

注意点:

1、友元函数不是类的成员函数,是一个全局函数‘

2、友元函数的声明可以放在类的任意位置,public,private,protected对friend声明无效

3、友元函数破坏了类的封装性,一般不建议试用

4、友元函数没有 this 指针,因为它是全局函数而不在类的内部

5、如果A类是B类的友元类,则A类的所有成员函数都是B类的友元函数



猜你喜欢

转载自blog.csdn.net/ljf_djcrs/article/details/79326329