[C++ の基礎: 22]: クラスの const オブジェクトと const メンバー関数/メソッド、およびクラス内の const に関連する一般的な問題!

この一連のC++ 関連記事は、あくまで著者の学習メモであり、私自身の理解に基づいて学習を記録していきます。C++ 学習シリーズは、基礎、STL、および高度なデータ構造とアルゴリズムの3 つの段階に分かれており、関連する主な内容は次のとおりです。

  1. 基本:クラスとオブジェクト(C++ の 3 つの主要な機能など)。
  2. STL : C++ が提供する STL 関連ライブラリの使用方法を学びます
  3. 高次データ構造とアルゴリズム:独自の STL ライブラリを手動で実装し、 B ツリー、B+ ツリー、赤黒ツリーなどの高次データ構造を設計および実装します

学習セット:


この号の内容: [C++ 基礎: 22]: クラスの const メンバー変数/属性と const メンバー関数/メソッド、およびクラス内の const に関連する一般的な問題!


内容:
1. const メンバー関数の基本的な理解
2. コード例で議論すべき質問: クラスの const オブジェクト
- - 2.1 直接的な式の分析
- - 2.2 コード分析との組み合わせ
3. const メンバー関数の書き方!
- - 3.1 基本的な書き方の枠組み
- - 3.2 エラーコード例の修正とテスト結果
4. クラスの const に関するよくある問題!
5. おすすめ関連記事


[ C++学習集リンク]


1. const メンバー関数の基本的な理解

  • const で変更された「メンバー関数」を const メンバー関数と呼びます。

  • const はクラスのメンバー関数を変更し、実際にはメンバー関数内で暗黙的に this ポインターを変更します。これは、クラスのメンバーがメンバー関数内で変更できないことを示します。(理解方法については、2つ目の分析ポイントと3つ目のポイントの実際の使用方法を参照してください)

注: これには、前のコンテンツで説明したクラスの *この問題が含まれます:クリックすると、関連する記事に直接移動します


2. 問題を議論するためのコード例!

コードを読むときは、const で変更されたメンバー関数の意味を思い出してください。メンバー関数の暗黙的な this ポインターの実際の変更は、メンバー関数内でクラスのメンバーを変更できないことを示します。


質問: 次のコードは正常に実行できますか? [分析と議論、コードの後のテキスト内容を見てください]

#include<iostream>
using std::cout;
using std::endl;

class Date {
public:
	Date(int year = 2000, int month = 1, int day = 1) {
		_year = year;
		_month = month;
		_day = day;
	}
	void Print() {
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main() {
	// 此前学习的基本示例化方式
	Date d1(2023, 5, 23);

	// 使用 const 修饰实例化对象!
	const Date d2(2023, 5, 24);
	d1.Print();
	d2.Print();

	return 0;
}

操作結果:

ここに画像の説明を挿入します


2.1 直接的な発現解析

画像からわかるように、プログラムはエラーを報告します。上記のコードでは、インスタンス化の例で const 変更が使用されています。前回のクラスの紹介で述べたことを思い出してください。クラスは、「*this ポインター」を通じてさまざまなインスタンス オブジェクトの識別を実現します。先ほど説明した「*this ポインター」は、クラス内のメンバー関数の最初の (隠し) パラメーターです。その形式は次のとおりです: typename* const this !

/* 以构造函数为例 */
void Date( Date* const this, int year, int month, int day){]

明らかに、エラー レポートから、使用している d2 オブジェクトが実際には const 変更されていることがわかります。言い換えれば、 d2 を識別する「*this ポインター」も const で変更する必要があります。しかし、以前の"*this pointer"の紹介を振り返ると、この非表示のデフォルト パラメータの送受信を表示できないと述べました。では、この問題をどうやって解決すればよいでしょうか?


解決策: 前回の紹介によると、const メンバー関数の役割は何ですか?


2.2 コード分析との組み合わせ

まず、インスタンス化された 2 つのオブジェクトに注目してください。(文字通りの違いは、const 変更があるかどうかです。)

// 使用 引用与指针的权限思路理解
Date d1(2023, 5, 23);			// 可读可写
const Date d2(2023, 5, 24);		// 只可读

Print() 関数に注意してください。パラメータのタイプに注意してください。

// 函数字面声明的原型如下:
void Print() {}
// 实际中编译器会翻译作:
void Print(Date* const this){}	

/* 
	简而言之,就是隐藏了 this 指针!
	且 this 指针是被 const 修饰(注意 const 在 * 之后的意义!!!)!
*/

インスタンス化された 2 つのオブジェクト自体を振り返ってみます。

// 字面形式
Date d1(2023, 5, 23);			
const Date d2(2023, 5, 24);	

// 编译器翻译的形式:
Date d1(&d1, 2023, 5, 23);			
const Date d2(&d2, 2023, 5, 24);	

/*
	注意:
		&d1、&d2 是什么类型?
*/

次のステートメントを実行して結果を取得します。

/* 执行以下语句: */
cout << typeid(&d1).name() << endl;
cout << typeid(&d2).name() << endl;
/* 结果: */
class Date *
class Date const *

ここに画像の説明を挿入します


上記の結果と関数のパラメーターの型を組み合わせると、問題がわかります。

/*
	&d1:Date *
	&d2:Date const *
	函数参数:Date * 【 const 只是修饰指针的! 】
	从权限角度看来,函数接收的是可读可写参数,传递过来的是只读!在函数内使用时就是权限放大(不可行!只能平行或缩小!)
	
	由此:得出问题的关键就是在于参数问题!
	由此前知识点可知:类的默认隐含参数是不可以显示接收及传递的!那该如何使 Date * => Date const *
	解决方案:const 成员函数【 const 修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。 】
*/

3. constメンバー関数の書き方!

3.1 基本的な執筆フレームワーク

基本的な書き方は以下の通りです。

type function_name() const	/* 注意 const 的位置及作用 */
{
    
}

3.2 エラーコード例を変更して結果をテストする

Print() 関数を変更してください。

void Print() const	/* 注意此处修改! */
{
	cout << _year << "-" << _month << "-" << _day << endl;
}

ここに画像の説明を挿入します


4. クラス内の const に関連する一般的な問題!

  1. const オブジェクトは非 const メンバー関数を呼び出すことができますか?
  2. 非 const オブジェクトは const メンバー関数を呼び出すことができますか?
  3. const メンバー関数は他の非 const メンバー関数を呼び出すことができますか?
  4. 他の const メンバー関数を非 const メンバー関数内で呼び出すことはできますか?
  5. 同じ名前の関数は、const の変更の有無にかかわらずオーバーロードを構成しますか?

ヒント:真実をテストするための唯一の基準は実践です。


5. おすすめ関連記事

1. C++ 学習::[基礎: 11]: C++ クラスと非静的 this ポインターの基本的な使用法 (面接テスト 2 点): クラスの null ポインターの問題 (このポインターは null であってもよいか?) | このポインターはどこに存在するか?

おすすめ

転載: blog.csdn.net/weixin_53202576/article/details/131071535