C++中构造函数的属性初始化方式

关键代码:

Student(int id,char *t1_n, char* t2_n) : t1(t1_n), t2(t2_n){
		this->id = id;
		cout << "Student有参构造函数" << endl;
	}

详细练习代码

//构造函数的属性初始化列表

class Teacher{
private:
	char* name;
public:
	Teacher(char* name){
		this->name = name;
		cout << "Teacher有参构造函数" << endl;
	}
	~Teacher(){
		cout << "Teacher析构函数" << endl;
	}
	char* getName(){
		return this->name;
	}

};

class Student{
private:
	int id;
	//属性对象
	//Teacher t = Teacher("miss cang");
	Teacher t1;
	Teacher t2;
public:
	Student(int id,char *t1_n, char* t2_n) : t1(t1_n), t2(t2_n){
		this->id = id;
		cout << "Student有参构造函数" << endl;
	}
	void myprint(){
		cout << id << "," << t1.getName() <<"," << t2.getName() << endl;
	}
	~Student(){
		cout << "Student析构函数" << endl;
	}
};

void func(){
	Student s1(10, "miss bo", "mrs liu");
	//Student s2(20, "miss cang", "jason");
	s1.myprint();
	//s2.myprint();
}

void main(){
	func();

	system("pause");
}

构造顺序:里面的属性对象先构造,外层对象后构造。 析构顺序:外层对象先构造,里面的属性对象后构造。


释放方式

//C++ 通过new(delete)动态内存分配
//C	  malloc(free)
class Teacher{
private:
	char* name;
public:
	Teacher(char* name){
		this->name = name;
		cout << "Teacher有参构造函数" << endl;
	}
	~Teacher(){
		cout << "Teacher析构函数" << endl;
	}
	void setName(char* name){
		this->name = name;
	}
	char* getName(){
		return this->name;
	}
};

void func(){
	//C++	
	//会调用构造和析构函数
	Teacher *t1 = new Teacher("jack");
	cout << t1->getName() << endl;
	//释放
	delete t1;

	//C
	//Teacher *t2 = (Teacher*)malloc(sizeof(Teacher));
	//t2->setName("jack");
	//free(t2);
	
}

void main(){
	func();
	//数组类型
	//C
	//int *p1 = (int*)malloc(sizeof(int) * 10);
	//p1[0] = 9;
	//free(p1);
	
	//C++
	int *p2 = new int[10];
	p2[0] = 2;
	//释放数组 []
	delete[] p2;

	system("pause");
}


static 静态属性和方法

class Teacher{
public:
	char* name;
	//计数器
	static int total;
public:
	Teacher(char* name){
		this->name = name;		
		cout << "Teacher有参构造函数" << endl;
	}
	~Teacher(){
		cout << "Teacher析构函数" << endl;
	}
	void setName(char* name){
		this->name = name;
	}
	char* getName(){
		return this->name;
	}
	//计数,静态函数
	static void count(){
		total++;		
		cout << total << endl;
	}
};

//静态属性初始化赋值
int Teacher::total = 9;

void main(){
	Teacher::total++;
	cout << Teacher::total << endl;
	//直接通过类名访问
	Teacher::count();

	//也可以通过对象名访问
	Teacher t1("yuehang");
	t1.count();

	system("pause");
}

类的大小


class A{
public:
	int i;
	int j;
	int k;
	static int m;
};

class B{
public:
	int i;
	int j;
	int k;
	void myprintf(){
		cout << "打印" << endl;
	}
};


void main(){
	cout << sizeof(A) << endl;
	cout << sizeof(B) << endl;

	//C/C++ 内存分区:栈、堆、全局(静态、全局)、常量区(字符串)、程序代码区(函数)
	//字符串char* 存在于常量区,不能被修改;字符数组存在于堆上,可以被修改
	//普通属性与结构体相同的内存布局

	//JVM Stack(基本数据类型、对象引用)
	//Native Method Stack(本地方法栈)
	//方法区
	

	system("pause");
}

输出结果是: 12 12


this,当前对象的指针

函数是共享的,必须要有能够标识当前对象是谁的办法

class Teacher{
private:
	char* name;
	int age;
public:
	Teacher(char* name,int age){
		this->name = name;
		this->age = age;
		cout << "Teacher有参构造函数" << endl;
	}
	~Teacher(){
		cout << "Teacher析构函数" << endl;
	}
	//常函数,修饰的是this
	//既不能改变指针的值,又不能改变指针指向的内容
	//const Teacher* const this
	void myprint() const{
		printf("%#x\n",this);
		//改变属性的值
		//this->name = "yuehang";
		//改变this指针的值
		//this = (Teacher*)0x00009;
		cout << this->name << "," << this->age << endl;
	}
	void myprint2(){		
		cout << this->name << "," << this->age << endl;		
	}
};

void main(){
	Teacher t1("jack",20);
	const Teacher t2("rose", 18);
	//t2.myprint2(); 常量对象只能调用常量函数,不能调用非常量函数
	//常函数,当前对象不能被修改,防止数据成员被非法访问
	printf("%#x\n", &t1);
	t1.myprint();

	printf("%#x\n", &t2);
	t2.myprint();

	system("pause");
}

友元函数

class A{
	//友元函数
	friend void modify_i(A *p, int a);
private:
	int i;
public:
	A(int i){
		this->i = i;
	}
	void myprint(){
		cout << i << endl;
	}
	
};

//友元函数的实现,在友元函数中可以访问私有的属性
void modify_i(A *p, int a){
	p->i = a;
}

void main(){
	A* a = new A(10);
	a->myprint();

	modify_i(a,20);
	a->myprint();

	system("pause");
}

友元类

可以想到:class类是所有类的友元类

class A{		
	//友元类
	friend class B;
private:
	int i;
public:
	A(int i){
		this->i = i;
	}
	void myprint(){
		cout << i << endl;
	}	
};

class B{
public:
	//B这个友元类可以访问A类的任何成员
	void accessAny(){
		a.i = 30;		
	}
private:
	A a;
};

运算符重载

class Point{
public:
	int x;
	int y;
public:
	Point(int x = 0, int y = 0){
		this->x = x;
		this->y = y;
	}
	void myprint(){
		cout << x << "," << y << endl;
	}
};

//重载+号
Point operator+(Point &p1, Point &p2){
	Point tmp(p1.x + p2.x, p1.y + p2.y);
	return tmp;
}

//重载-号
Point operator-(Point &p1, Point &p2){
	Point tmp(p1.x - p2.x, p1.y - p2.y);
	return tmp;
}

void main(){
	Point p1(10,20);
	Point p2(20,10);
	
	Point p3 = p1 + p2;

	p3.myprint();

	system("pause");
}

成员函数,运算符重载

class Point{
public:
	int x;
	int y;
public:
	Point(int x = 0, int y = 0){
		this->x = x;
		this->y = y;
	}
	//成员函数,运算符重载
	Point operator+(Point &p2){
		Point tmp(this->x + p2.x, this->y + p2.y);
		return tmp;
	}
	void myprint(){
		cout << x << "," << y << endl;
	}
};

void main(){
	Point p1(10, 20);
	Point p2(20, 10);

	//运算符的重载,本质还是函数调用
	//p1.operator+(p2)
	Point p3 = p1 + p2;

	p3.myprint();

	system("pause");
}

当属性私有时,通过友元函数完成运算符重载

class Point{
	friend Point operator+(Point &p1, Point &p2);
private:
	int x;
	int y;
public:
	Point(int x = 0, int y = 0){
		this->x = x;
		this->y = y;
	}	
	void myprint(){
		cout << x << "," << y << endl;
	}
};

Point operator+(Point &p1, Point &p2){
	Point tmp(p1.x + p2.x, p1.y + p2.y);
	return tmp;
}

void main(){
	Point p1(10, 20);
	Point p2(20, 10);

	//运算符的重载,本质还是函数调用
	//p1.operator+(p2)
	Point p3 = p1 + p2;

	p3.myprint();

	system("pause");
}