まず、このポインターとメンバーメソッドの関係
前の記事で書いたコモディティクラスを見てみましょう。その中のすべてのメンバーメソッドは通常のメンバーメソッドであることがわかっています。
商品コードは次のように実装されています。
class CDate
{
public:
CDate(int y, int m, int d)
{
_year = y;
_month = m;
_day = d;
}
void show()
{
cout << _year << "/" << _month << "/" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
class CGoods
{
public:
CGoods(const char* n, int a, double p,int y,int m,int d):_data(y,m,d)
{
strcpy(_name, n);
_amount = a;
_price = p;
}
void show()
{
cout << "name: " << _name << endl;
cout << "amount:" << _amount << endl;
cout << "price:" << _price << endl;
_data.show();
}
private:
char _name[20];
int _amount;
double _price;
CDate _data;
};
1.通常のメンバーメソッド
コンパイル後、オブジェクトのアドレスが実際のパラメーターとして関数に渡されるため、通常のメンバーメソッドをオブジェクトから呼び出す必要があります。コンパイルプロセス中に、これらのメンバーメソッドはこのパラメーター変数を追加して、呼び出し元のオブジェクトを受信します。
彼には以下の特徴があります。
- クラスに属するスコープ
- このメソッドを呼び出すときはオブジェクトに依存する必要があります(多くの場合、オブジェクトを呼び出せません)
- オブジェクトに任意にアクセスできるプライベートメンバー変数は、保護されているとは見なさず、パブリックとプライベートのみを考慮する
2.静的メンバーメソッド
前述の商品カテゴリに要件を追加する場合は、すべての商品の総数をカウントします
改善点1:コンストラクターに_count ++を追加し、生成されたすべての新しいオブジェクトの数を記録する
CGoods(const char* n, int a, double p, int y, int m, int d)
:_data(y, m, d)
{
strcpy(_name, n);
_amount = a;
_price = p;
_count++;
}
改善2:すべての商品によって共有される情報を印刷するために静的メンバーメソッドを追加する
static void showCGoodsCount()
{
cout << "所有商品的种类数量是: " << _count << endl;
}
改善3:プライベートで静的メンバー変数を定義します。
private:
char _name[20];
int _amount;
double _price;
CDate _data;
static int _count;
これは、クラスの外部で定義および初期化される単なるステートメントであり、オブジェクトには属していませんが、クラスレベルに属しています。.dataセクションのオブジェクトメモリを占有しません
改善3:クラス外で初期化する
int CGoods::_count = 0;
静的メンバーメソッドの特性:このパラメーターは生成されません
-
クラスに属するスコープ
-
クラス名スコープでメソッドを呼び出す
-
オブジェクトのプライベートメンバーに任意にアクセスできます。オブジェクトに依存しないメンバーに限定されます(他の静的メンバーのみを呼び出すことができます)
通常のメンバーメソッドと静的メンバーメソッドの違い:
前者にはCGoods *があり、後者にはこのポインターは必要ありません。オブジェクト呼び出しのアドレスを受け取る必要はありません。
3.通常のメンバーメソッド
上記の商品クラスに基づいて要件を追加します。メイン関数で商品オブジェクトを宣言するには、商品を表示することしかできません
int main()
{
const CGoods good5("非卖品商品5",100, 35.0, 2019, 5, 12);
good5.show();
return 0;
}
ここで呼び出される共通メソッドshow()は間違っていることに注意してください。共通オブジェクトが共通メソッドCGoods :: show(&good5)const CGoods *-> CGoods *このエラーを呼び出すため、共通オブジェクトによって呼び出されるメソッドは通常のメソッドでなければなりません
改善1:ショーの一般的な方法を定義する
void show() const//const CGoods *this
{
cout << "name: " << _name << endl;
cout << "amount:" << _amount << endl;
cout << "price:" << _price << endl;
_data.show();
}
時間で呼ばれるショーも通常の方法でなければなりません
void show() const
{
cout << _year << "/" << _month << "/" << _day << endl;
}
定数メンバーメソッド、および通常のメンバーメソッドは、通常のオブジェクトと定数オブジェクトをオーバーロードできます。読み取り専用操作のメンバーメソッドである限り、すべての定数定数メンバーメソッド
定数メンバーメソッドの機能:const CGoods * thisを生成します
- クラスに属するスコープ
- 呼び出しは、通常のオブジェクトまたは通常のオブジェクトのいずれかのオブジェクトに依存します
- オブジェクトのプライベートメンバーに任意にアクセスできますが、読み取りのみが可能で、書き込みはできません
2、クラスメンバーへのポインター
そのようなクラスがあります:
class Test
{
public:
void func() { cout << "call Test :: func" << endl; }
static void static_func() { cout << "Test::static_func" << endl; }
int ma;
static int mb;
};
int Test::mb;
メンバー変数またはメソッドへのポインターを定義する場合、それをどのように実装する必要がありますか?
注意!ポインターの前には、クラススコープ(1)の通常のメンバー変数へのポインターを指定する必要が
あります。
Test t1;
Test* t2 = new Test();
int Test::* p = &Test::ma;
t1.*p = 20;
cout << t1.*p << endl;
t2->*p = 30;
cout << t2->*p << endl;
delete t2;
(2)オブジェクトに依存しない静的メンバー変数へのポインター
int* p1 = &Test::mb;
*p1 = 40;
cout << *p1 << endl;
(3)メンバーメソッドへのポインター(通常のメンバーメソッドはオブジェクトに依存する必要があります)
void (Test :: * pfunc)() = &Test::func;
(t1.*pfunc)();
(t2->*pfunc)();