C++ class and object learning [part3: object characteristics 2.0]

C++ class and object learning [part3: object characteristics 2.0]

Member variables and member functions are stored separately

In C++, member variables and member functions in a class are stored separately.
Only non-static member variables belong to objects of the class.
There are four kinds of members:

  • Non-static member variable
  • Static member variable
  • Non-static member function
  • Static member function

The specific display code is as follows:

// arrayone.cpp -- small arrays of integers
#include <iostream>

using namespace std;

#include <string>

class Person
{
    
    
public:
    Person()
    {
    
    
        mA = 0;
    }
    //非静态成员变量占对象空间
    int mA;
    //静态成员变量不占对象空间
    static int mB;
    //函数也不占对象空间,所有函数共享一个函数实例
    void func()
    {
    
    
        cout << "mA:" << this->mA << endl;
    }
    //静态成员函数也不占对象空间
    static void sfunc()
    {
    
    
    }
};

int main()
{
    
    
    cout << sizeof(Person) << endl;
    
    system("pause");
    return 0;
}

It should be noted that:
an empty class occupies one byte of memory. The purpose is to distinguish the memory locations occupied by different empty objects.
If it containsNon-static member variable, It occupies the number of bytes of the member variable.
If there are more than one, add up.

this pointer concept

The this pointer points to the object to which the called member function belongs. The
this pointer implies a pointer in each non-static member function. The
this pointer does not need to be defined. It can be used directly
.

  • When the formal parameter and the member variable have the same name, the this pointer can be used to distinguish
  • To return the object itself in the non-static member function of the class, you can use return *this

The following code is an example of returning the object itself:

Person& PersonAddPerson(Person p)
	{
    
    
		this->age += p.age;
		//返回对象本身
		return *this;
	}

In this way, recursive calls can be used when calling:

p2.PersonAddPerson(p1).PersonAddPerson(p1).PersonAddPerson(p1);

Null pointer access to member functions

We can define a pointer to a class, but make it empty (I don't really understand what this is for now).
This null pointer can call member functions, but pay attention to whether the this pointer is used.
The main body of the program is as follows:

//空指针访问成员函数
class Person {
    
    
public:

	void ShowClassName() {
    
    
		cout << "我是Person类!" << endl;
	}

	void ShowPerson() {
    
    
		if (this == NULL) {
    
    
			return;
		}
		cout << mAge << endl;
	}

public:
	int mAge;
};

void test01()
{
    
    
	Person * p = NULL;
	p->ShowClassName(); //空指针,可以调用成员函数
	p->ShowPerson();  //但是如果成员函数中用到了this指针,就不可以了
}

int main() {
    
    

	test01();

	system("pause");

	return 0;
}

Points to pay attention to:

  • Null pointer definition method.
  • Null pointer call member function method.
  • Use member variables, can not use null pointers
  • If the above situation occurs, judgment statements should be used to increase the robustness of the program

const modified member function

Constant function:

  • After adding const after the member function, we call this function a constant function
  • Member properties cannot be modified in constant functions
  • After adding the keyword mutable in the member attribute declaration, it can still be modified in the normal function

Regular object:

  • Add const before declaring the object to call the object a constant object
  • Constant objects can only call constant functions

The main body of the test program is as follows:

class Person {
    
    
public:
	Person() {
    
    
		m_A = 0;
		m_B = 0;
	}

	//this指针的本质是一个指针常量,指针的指向不可修改
	//如果想让指针指向的值也不可以修改,需要声明常函数
	void ShowPerson() const {
    
    
		//const Type* const pointer;
		//this = NULL; //不能修改指针的指向 Person* const this;
		//this->mA = 100; //但是this指针指向的对象的数据是可以修改的

		//const修饰成员函数,表示指针指向的内存空间的数据不能修改,除了mutable修饰的变量
		this->m_B = 100;
	}

	void MyFunc() const {
    
    
		//mA = 10000;
	}

public:
	int m_A;
	mutable int m_B; //可修改 可变的
};


//const修饰对象  常对象
void test01() {
    
    

	const Person person; //常量对象  
	cout << person.m_A << endl;
	//person.mA = 100; //常对象不能修改成员变量的值,但是可以访问
	person.m_B = 100; //但是常对象可以修改mutable修饰成员变量

	//常对象访问成员函数
	person.MyFunc(); //常对象只能调用const的函数

}

int main() {
    
    

	test01();

	system("pause");

	return 0;
}

Points to be mastered:

  • How to define common objects
  • How to define regular functions (const is placed after the function name)
  • Constant objects can modify member variables modified by mutable
  • Constant objects can only call constant functions

Global function as friend

The friend key isfriend
Types of friends:

  1. Global function as friend
  2. Classmate
  3. Member function as friend

Global function as friend

For global functions as friends, the code is as follows:

// arrayone.cpp -- small arrays of integers
#include <iostream>

using namespace std;

#include <string>

class Building
{
    
    
    //告诉编译器 goodGay全局函数 是 Building类的好朋友,可以访问类中的私有内容
    friend void goodGay(Building *building);

public:
    Building()
    {
    
    
        this->m_SittingRoom = "客厅";
        this->m_BedRoom = "卧室";
    }

public:
    string m_SittingRoom; //客厅

private:
    string m_BedRoom; //卧室
};

void goodGay(Building *building)//这里用的是指针传递
{
    
    
    cout << "好基友正在访问: " << building->m_SittingRoom << endl;
    cout << "好基友正在访问: " << building->m_BedRoom << endl;
}

void test01()
{
    
    
    Building b;
    goodGay(&b);//传入对象的地址
}

int main()
{
    
    

    test01();

    system("pause");
    return 0;
}

My understanding is to declare a global function in the class, so that this function can access the private members of the class, the declaration method is as follows.
(Do not consider what permissions are)

friend void goodGay(Building *building);

In addition, the address (pointer) transfer is used in this example, and the pointer of the class is transferred. You must learn this usage.

Classmate

The class is a friend, so that the friend class can access the private member variables in the original class. The code is as follows:

// arrayone.cpp -- small arrays of integers
#include <iostream>

using namespace std;

#include <string>
class Building;
class goodGay
{
    
    
public:
    goodGay();
    void visit();

private:
    Building *building;//定义了Building类的指针
};

class Building
{
    
    
    //告诉编译器 goodGay类是Building类的好朋友,可以访问到Building类中私有内容
    friend class goodGay;

public:
    Building();

public:
    string m_SittingRoom; //客厅
private:
    string m_BedRoom; //卧室
};

Building::Building()
{
    
    
    this->m_SittingRoom = "客厅";
    this->m_BedRoom = "卧室";
}

goodGay::goodGay()
{
    
    
    //这是一个初始化类的构造函数
    building = new Building;//building是goodgay类中的成员,这里对他进行了初始化,并且采用的是new指针方式
}

void goodGay::visit()
{
    
    
    cout << "好基友正在访问" << building->m_SittingRoom << endl;
    cout << "好基友正在访问" << building->m_BedRoom << endl;//访问了私有权限
}

void test01()
{
    
    
    goodGay gg;
    gg.visit();
}

int main()
{
    
    

    test01();

    system("pause");
    return 0;
}

Here we use pointers as the class definition and use the new operator. It is not clear why we did this.
The important thing is to declare in the Building class:

friend class goodGay;

Thus the Building class contains the goodGay class as a friend.

Member function as friend

A member function is a function defined in a class. If we want to use a function in one class and use the function to access private members in another class, we can use the member function as a friend in the latter class. The specific code is as follows:

// arrayone.cpp -- small arrays of integers
#include <iostream>

using namespace std;

#include <string>

class Building;

class GoodGay
{
    
    
public:
    GoodGay();
    void visit();  //让visit函数可以访问Building中私有成员
    void visit2(); //让visit2函数不可以访问Building中私有成员

    Building *building;
};

class Building
{
    
    
    //告诉编译器,GoodGay类下的visit成员函数作为本类的好朋友,可以访问私有成员
    friend void GoodGay::visit();

public:
    Building();

public:
    string m_LivingRoom; //客厅

private:
    string m_BedRoom; //卧室
};
//类外实现成员函数
Building::Building()
{
    
    
    m_LivingRoom = "客厅";
    m_BedRoom = "卧室";
}
GoodGay::GoodGay()
{
    
    
    building = new Building; //在堆区创建Building对象,并用指针building维护!!
}
void GoodGay::visit()
{
    
    
    cout << "visit 正在访问" << building->m_LivingRoom << endl;
    cout << "visit 正在访问" << building->m_BedRoom << endl;
}
void GoodGay::visit2()
{
    
    
    cout << "visit2 正在访问: " << building->m_LivingRoom << endl;
    //cout << "visit 正在访问" << building->m_BedRoom << endl;//不可以访问
}

void test01()
{
    
    
    GoodGay gg;
    gg.visit();
    gg.visit2();
}
int main()
{
    
    
    test01();
    system("pause");
    return 0;
}

Among them, the more important is the sentence "declaration":

//告诉编译器,GoodGay类下的visit成员函数作为本类的好朋友,可以访问私有成员
friend void GoodGay::visit();

In this way, the visit function under the GoodGay class can access the private member variables in the Building class.
It is worth mentioning that the
same effect can be achieved by replacing this with class as a friend.
So let's just think that member function as a friend is a more refined way of friend declaration (purely my guess).

Guess you like

Origin blog.csdn.net/qq_41883714/article/details/109478662