C ++クラスとオブジェクトの学習[パート3:オブジェクトの特性2.0]
メンバー変数とメンバー関数は別々に保存されます
C ++では、クラス内のメンバー変数とメンバー関数は別々に格納されます。
非静的メンバー変数のみがクラスのオブジェクトに属します。
メンバーには次の4種類があります。
- 非静的メンバー変数
- 静的メンバー変数
- 非静的メンバー関数
- 静的メンバー関数
具体的な表示コードは次のとおりです。
// 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;
}
空のクラスは1バイトのメモリを占有することに注意してください。目的は、さまざまな空のオブジェクトが占有するメモリ位置を区別することです。
含まれている場合非静的メンバー変数、メンバー変数のバイト数を占めます。
複数ある場合は、合計します。
このポインタの概念
thisポインターは、呼び出されたメンバー関数が属するオブジェクトを
指します。このポインターは、すべての非静的メンバー関数を意味する一種のポインターです。thisポインターは、
定義する必要はありません。
目的のために直接使用できます。このポインタ:
- 仮パラメーターとメンバー変数の名前が同じ場合、このポインターを使用して区別できます
- クラスの非静的メンバー関数でオブジェクト自体を返すには、return * thisを使用できます。
次のコードは、オブジェクト自体を返す例です。
Person& PersonAddPerson(Person p)
{
this->age += p.age;
//返回对象本身
return *this;
}
このようにして、以下を呼び出すときに再帰呼び出しを使用できます。
p2.PersonAddPerson(p1).PersonAddPerson(p1).PersonAddPerson(p1);
メンバー関数へのNULLポインターアクセス
クラスへのポインタを定義することはできますが、それを空にします(これが今のところ何であるかはよくわかりません)。
このnullポインターはメンバー関数を呼び出すことができますが、このポインターが使用されているかどうかに注意してください。
プログラムの本体は次のとおりです。
//空指针访问成员函数
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;
}
注意すべき点:
- ヌルポインタ定義メソッド。
- ヌルポインター呼び出しメンバー関数メソッド。
- メンバー変数を使用します。nullポインターは使用できません
- 上記の状況が発生した場合は、プログラムの堅牢性を高めるために判断ステートメントを使用する必要があります
const変更されたメンバー関数
定数関数:
- メンバー関数の後にconstを追加した後、この関数を定数関数と呼びます
- 定数関数でメンバープロパティを変更することはできません
- メンバー属性宣言に変更可能なキーワードを追加した後でも、通常の関数で変更できます。
通常のオブジェクト:
- オブジェクトを定数オブジェクトと呼ぶようにオブジェクトを宣言する前にconstを追加します
- 定数オブジェクトは定数関数のみを呼び出すことができます
テストプログラムの本体は次のとおりです。
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;
}
習得すべきポイント:
- 共通オブジェクトを定義する方法
- 通常の関数を定義する方法(constは関数名の後に配置されます)
- 定数オブジェクトは、可変によって変更されたメンバー変数を変更できます
- 定数オブジェクトは定数関数のみを呼び出すことができます
友達としてのグローバル機能
友達の鍵は友達
友達の種類:
- 友達としてのグローバル機能
- 同級生
- メンバーは友達として機能します
友達としてのグローバル機能
フレンドとしてのグローバル関数の場合、コードは次のとおりです。
// 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;
}
私の理解では、この関数がクラスのプライベートメンバーにアクセスできるように、クラスでグローバル関数を宣言します。宣言メソッドは次のとおりです。
(権限が何であるかを考慮しないでください)
friend void goodGay(Building *building);
また、この例では、アドレス(ポインタ)転送を使用し、クラスのポインタを転送しています。この使い方を学ぶ必要があります。
同級生
このクラスはフレンドであるため、フレンドクラスは元のクラスのプライベートメンバー変数にアクセスできます。コードは次のとおりです。
// 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;
}
ここでは、クラス定義としてポインターを使用し、new演算子を使用していますが、なぜこれを行ったのかは明確ではありません。
重要なことは、Buildingクラスで宣言することです。
friend class goodGay;
したがって、Buildingクラスには、フレンドとしてgoodGayクラスが含まれています。
メンバーは友達として機能します
メンバー関数は、クラスで定義された関数です。あるクラスの関数を使用し、その関数を使用して別のクラスのプライベートメンバーにアクセスする場合は、メンバー関数を後者のクラスのフレンドとして使用できます。特定のコード以下のとおりであります:
// 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;
}
それらの中で、より重要なのは「宣言」という文です。
//告诉编译器,GoodGay类下的visit成员函数作为本类的好朋友,可以访问私有成员
friend void GoodGay::visit();
このようにして、GoodGayクラスのvisit関数は、Buildingクラスのプライベートメンバー変数にアクセスできます。
これを
友達としてのクラスに置き換えることで同じ効果が得られることは言及する価値があります。
ですから、友達を作るメンバー関数は、友達宣言のより洗練された方法であると考えてみましょう(純粋に私の推測です)。