A brief discussion of C++|class members

1. Class objects as class members

A class can be a member of another class

Code: 

#include <iostream>
using namespace std;
class phone {
public:
	string shouji;
	phone(string shouji1) :shouji(shouji1) {
		cout << "phone的构造函数调用" << endl;
	}
	~phone() {
		cout << "phone的析构函数调用" << endl;
	}
};
class person {
public:
	int age;
	string name;
	phone shouji;
	//隐式转换相当于shouji=phone(shouji1)
	person(int a, string name1, string shouji1) :age(a), name(name1), shouji(shouji1) {
		cout << "person的构造函数调用" << endl;
	}
	~person() {
		cout << "person的析构函数调用" << endl;
	}
};
void fun() {
	person p(23, "小明", "苹果");
}
int main() {
	fun();
	return 0;
}

 Notice:

When creating a class, the constructor of the contained class is called first, and then the constructor of the outer class is called. When destructing 1, it is just the opposite. The outer class is destructed first, and then the inner class is destructed.

2. Static members 

Static members are called static members by adding the static keyword in front of the member variables.

Static members are divided into static member variables and static member functions .

2.1 Static member variables

. All objects share the same data

. Memory is allocated during the compilation phase.

. In-class declaration, out-of-class initialization·static member function

 Static members must be initialized outside the class, otherwise the compiler will think that they are only declared but not actually defined, and a link error will occur.

Code: 

#include <iostream>
using namespace std;
class person {
public:
	static int age;
};
int person::age = 10;
void fun() {
	person p;
	p.age = 90;
	person p1;
	cout << p1.age << endl;
}
int main() {
	fun();
	return 0;
}

 Static member variables can be accessed not only through objects, but also through class names. Static member variables also have access rights.

Code: 

#include <iostream>
using namespace std;
class person {
public:
	static int age;
};
int person::age = 10;
void fun() {
	person p;
	p.age = 90;
	cout << person::age << endl;
}
int main() {
	fun();
	return 0;
}

2.2 Static member functions

. All objects share the same function

. Static member functions can only access static member variables

Code: 

#include <iostream>
using namespace std;
class person {
public:
	static int age;
	static void fun(int a) {
		age = a;          //只能调用静态成员变量
		cout << "静态函数fun调用" << endl;
	}
};
int person::age = 100;
void dioayong() {
	person p;
	p.fun(99);          //对象调用
	person::fun(66);   //类名调用
	cout << p.age << endl;
}
int main() {
	dioayong();
	return 0;
}

Similarly, static member functions can also be called through class names. It should be noted that static member functions can only call static member variables.

 3.this pointer

3.1 Storage of member variables and functions

In C++, member variables and member functions within a class are stored separately

Only non-static member variables belong to objects of the class

In C++, empty classes also occupy one byte. The C++ compiler will also allocate a byte space for each empty object in order to distinguish the location of the object in memory .

Code: 

#include <iostream>
using namespace std;
class person {

};
void fun() {
	person p;
	cout<<sizeof(p);
}
int main() {
	fun();
	return 0;
}

 The class also has the feature of memory alignment

Code: 

#include <iostream>
using namespace std;
class person {
public:
	int a;
	char b;
};
void fun() {
	person p;
	cout<<sizeof(p);
}
int main() {
	fun();
	return 0;
}

 In addition, neither member functions nor static member variables are stored on the class, that is, only non-static member variables are stored in the class

Code: 

#include <iostream>
using namespace std;
class person {
public:
	int a;
	static int b;
	void fun() {
		cout << "fun函数调用" << endl;
	}
	static void fun1() {
		cout << "fun1函数调用" << endl;
	}
};
int person::b = 10;
void fun() {
	person p;
	cout<<sizeof(p);
}
int main() {
	fun();
	return 0;
}

 3.2Usage of this pointer

Each non-static member function will only create one function instance , which means that multiple objects of the same type will share a piece of code. So the question is: How does this piece of code distinguish which object calls itself?

C++ solves the above problems by providing a special object pointer, the this pointer . This pointer points to the object to which the called member function belongs

 Notice:

1.This pointer is a pointer implicit in each non-static member function

2. This pointer does not need to be defined, it can be used directly

The purpose of this pointer: 

·When formal parameters and member variables have the same name, the this pointer can be used to distinguish formal parameters and variables with the same name.

·To return the object itself in a non-static member function of a class, use return *this

 Code:

#include <iostream>
using namespace std;
class people {
public:
	int age;
	people(int age) {
		this->age = age;
	}
};
void zhixing() {
	people p(10);
	cout << p.age << endl;
}
int main() {
	zhixing();
	return 0;
}

When returning itself, be careful to return a reference type. When returning a common value type, the return value is a copy of itself.

#include <iostream>
using namespace std;
class people {
public:
	int age;
	people(int age) {
		this->age = age;
	}
	 people& add(const people& p) {
		this->age += p.age;
		return *this;
	}
};
void zhixing() {
	people p1(10);
	people p2(20);
	p2.add(p1).add(p1).add(p1).add(p1);
	cout << p2.age << endl;
}
int main() {
	zhixing();
	return 0;
}

4. Null pointer access to member functions

In C++, null pointers can also call member functions, but you should also pay attention to whether the this pointer is used.

Code: 

#include <iostream>
using namespace std;
class person {
public:
	int age;
	void fun1() {
		cout << "fun1调用" << endl;
	}
	void fun2() {
		cout << "fun2调用" << age << endl;
	}

};
void diaoyong() {
	person* p = NULL;
	p->fun1();
	p->age = 10;
	p->fun2();
}
int main() {
	diaoyong();
	return 0;
}

 Only functions without this pointers can be called successfully, because this is a null pointer at this time, and calls containing this

 Code:

#include <iostream>
using namespace std;
class person {
public:
	int age;
	void fun1() {
		cout << "fun1调用" << endl;
	}
	void fun2() {
		if (this == NULL) {
			return;
		}
		cout << "fun2调用" << age << endl;
	}

};
void diaoyong() {
	person* p = NULL;
	p->fun1();
	p->fun2();
}
int main() {
	diaoyong();
	return 0;
}

Increase the robustness of the code and jump out of the function when it is judged that this pointer is a null pointer.

 5. const modified member function

 Constant function:

1. After adding const to the member function, we call this function a constant function.

2. Member attributes cannot be modified within a constant function.

3. After adding the keyword mutable when declaring a member attribute , it can still be modified in a constant function.

Common objects:

1. Add const before declaring an object to call it a constant object.

2. Constant objects can only call constant functions and member variables modified with mutable .

 5.1Constant functions

The essence of this pointer is a pointer constant. The pointer pointed to cannot be modified (person* const this), but the value of the address pointed to by this pointer can be changed.

 Constant function const should be added after the function parameter list

Code: 

#include <iostream>
using namespace std;
class person {
public:
	int age;
	void showage(int m) const{
	//	age = 89; //报错
		m = 100;
		cout << "age=" << age <<" m=" << m << endl;
	}
};
void fun() {
	person p;
	p.age = 10;
	p.showage(7);
}
int main() {
	fun();
	return 0;
}

 At this time, the compiler will report an error, and age cannot be changed within the function. But the parameters passed by the function can still be changed.

#include <iostream>
using namespace std;
class person {
public:
	mutable int age;
	void showage(int m) const{   //常函数
		age = 89; //报错
		m = 100;
		cout << "age=" << age <<" m=" << m << endl;
	}
};
void fun() {
	person p;
	p.age = 10;
	p.showage(7);
}
int main() {
	fun();
	return 0;
}

After adding the keyword mutable when declaring a member attribute, it can still be modified in a constant function.

5.2 Constant objects

 Code:

#include <iostream>
using namespace std;
class person {
public:
	mutable int age;
	void showage1(int m) const{
		//age = 89; //报错
		m = 100;
		cout << "age=" << age <<" m=" << m << endl;
	}
	void showage2(int m)  {
		age = 89;
		m = 100;
		cout << "age=" << age << " m=" << m << endl;
	}
};
void fun() {
	const person p;
	p.age = 10;      
	p.showage1(7);
	//p.showage2(7);  报错  
}
int main() {
	fun();
	return 0;
}

Constant objects can only call constant functions and member variables modified with mutable. Ordinary functions and ordinary member variables cannot be called

 6. Youyuan

Friend keyword: friend

Three implementations of friends:

1. Global functions as friends

2. Classes make friends

3. Member functions act as friends

6.1 Global functions as friends 

 Code:

#include <iostream>
using namespace std;

class home {
friend void func(home& p);
public:
	home(string keting, string woshi, string cuosuo):keting(keting),woshi(woshi),cuosuo(cuosuo) {

	}
	string keting;
private:
	string woshi;
protected:
	string cuosuo;
};

void func(home &p) {
	
	cout << p.keting << ' ' << p.woshi << ' ' << p.cuosuo << endl;
}
void fun() {
	home p("客厅", "卧室", "厕所");
	func(p);
}
int main() {
	fun();
	//cout << p.keting << ' ' << p.woshi << ' ' << p.cuosuo << endl;
	//保护和私有属性的不能访问
	return 0;
}

An elemental function is not a member function of the class, but it has permission to call all member variables of the class.

6.2 Category Friendship 

​​#include <iostream>
using namespace std;

class building {
friend class goodgay;   //声明友元类
public:
	building();
	string keting;
private:
	string cesuo;
protected:
	string woshi;
};
building::building() {
	keting = "客厅";
	cesuo = "厕所";
	woshi = "卧室";
}

class goodgay {
public:
	goodgay();
	void show();
private:
	building* p;
};
void goodgay::show() {
	cout << this->p->keting << ' ' << this->p->cesuo << ' ' << this->p->woshi << endl;
}
goodgay::goodgay() {
	p = new building;
}
void f() {
	goodgay a;
	a.show();
}
int main() {
	f();
	return 0;
}

 When a class is a friend, all member functions in the class can access all members in the friend class.

 6.3 Member functions as friends

 Code:

#include <iostream>
using namespace std;
class building;
class goodgay {
public:
	goodgay();
	void show1(building& p);
private:
	building* p;
};

class building {
friend void goodgay::show1(building& p);   //声明友元类
public:
	building();
	string keting;
private:
	string cesuo;
protected:
	string woshi;
};
building::building() {
	keting = "客厅";
	cesuo = "厕所";
	woshi = "卧室";
}


void goodgay::show1(building& p1) {
	cout <<p1.keting << ' ' << p1.cesuo << ' ' << p1.woshi << endl;
}
//void goodgay::show2() {
//	cout << this->p->ketipng << ' ' << this->p->cesuo << ' ' << this->p->woshi << endl;
//}
//无权限
goodgay::goodgay() {
	p = new building;
}
void f() {
	goodgay a;
	building b;
	a.show1(b);
}
int main() {
	f();
	return 0;
}

Note that the class must be declared first to prevent errors. Different from being a friend of a global function, a scope must be added.

Guess you like

Origin blog.csdn.net/m0_73731708/article/details/132927312