レビュー概要C ++(IV) - クラス

constメンバ関数とデータメンバー変更可能な変数

私たちは、このポインタのデフォルトのタイプは非常に定数ポインタ定数のクラス型バージョンへのポインタであることを知っています。これは、我々は一定のポインタバインド時にオブジェクト(が異なるため根本的なレベルののconst)でこれを置くことができない、問題をもたらすでしょう。このような、次の例のように。

class Solution
{
public:
	string isbn;
	string getIsbn() { return isbn; };
};


int main()
{
	const Solution s;
	s.getIsbn(); // 非法,因为this指针不能够指向const Solution类型对象
}

この時点で、我々はgetIsbn()メンバ関数は、定数として宣言されているのconstキーワードを使用することができ、その本質は、このポインタが一定のオブジェクトポインタ定数へのポインタで宣言することです。

	string getIsbn() const { return isbn; }; // 注意const的位置

このポインタの種類が溶液* CONST CONSTであるので、この時点で、次いで、正当にgetIsbn()を呼び出し、溶液const型のオブジェクトを指すことができます。しかし、このポインタは、そのオブジェクトの内容を変更できないので、constメンバ関数の呼び出しで、定数へのポインタです。あなたはそれを変更する必要がある場合は、対応するデータメンバーが変更可能(変数)を変更する必要があります。例えば:

class Solution
{
public:
	mutable string isbn;
	string getIsbn() const { isbn = "1"; return isbn; }; // 合法
};

さらに、構成はCONSTの関数として宣言することはできません。コンストラクタの初期化処理が完了するまで、我々はconstオブジェクトクラスを作成するときに、オブジェクトが実際にconst属性を作ったので。したがって、オブジェクトの構築のconstコンストラクタはそれを書く過程での値とすることができます。

型メンバ

そして、普通のメンバーと同様に、我々はまた、クラス内の特定の型の別名をカスタマイズすることができ、これは、型のメンバです。また、アクセス制限があります。

class Solution
{
public:
	using pos = int;
	pos size(string str) { return str.size(); };
};
int main()
{
	Solution::pos i; // pos是public的,因此可以被外部访问。
}

そして、普通のメンバーが異なっている、メンバーの種類は、使用後に定義する必要があります。

リターン*このメンバ関数

移動し、戻り値の型に設定されている以下のクラス、見ては、スクリーン&戻り、その戻り値が同じオブジェクトs1のために継続的に動作させることができます呼び出すオブジェクトへの参照があることを意味*このメンバ関数、あるプログラムの最後ので、結果出力は3,4です。

class Screen
{
public:
	friend ostream &print(ostream &cout, Screen &s);
	Screen &move(int dx, int dy) { cor_x += dx; cor_y += dy; return *this; };
	Screen &set(int x, int y) { cor_x = x; cor_y = y; return *this; };
private:
	int cor_x = 0;
	int cor_y = 0;
};

ostream &print(ostream &cout, Screen &s)
{
	cout << s.cor_x << "," << s.cor_y;
	return cout;
}

int main()
{
	Screen s1;
	s1.set(2, 3).move(1, 1);
	print(cout, s1); // 输出3,4
}

あなたはスクリーンタイプに移動し、戻り値を設定した場合、それは、この新しいオブジェクトの移動操作で、呼び出したセットの後に新しいオブジェクトを作成することと同じであるので、その結果は、2、3になり、S1自体値がセットのみ機能一度変更されます。

// 将move和set返回值改为Screen类型,其他不变。
int main()
{
	Screen s1;
	s1.set(2, 3).move(1, 1);
	// 等价于Screen temp = s1.set(2,3);temp.move(1,1);
	print(cout, s1); // 输出2,3
}

クラスメンバの宣言の検索のための名前

コンパイラは、すべての請求後に処理定義したクラスのメンバ関数を処理します。これを理解するために、私たちは、次の例を見ることができます:

typedef double Money;
string bal;
class Account
{
public:
	Money balance() { return bal; };
private:
	Money bal;
};

クラス全体を見ることができた後、関数の本体のバランスがゆえ、関数のreturn文ではなく、都市の範囲外の文字列オブジェクトよりも、BALという名前のメンバーを返し、処理されます。

しかし、メンバーの種類は、特別な治療であることが、次の例を見て。

typedef double Money;
string bal;
class Account
{
public:
	Money balance() { return bal; };
private:
	typedef int Money;
	Money bal;
};

内側範囲は、外側のスコープ名を再定義することができるので、コードは合法的であるからです。しかし、コンパイラは、初めての別名の前に定義の別名を見つけることに注意してください。コード例では、マネー残高()は実際には、外側層マネーマネーにより定義される二重型、お金マネーBALは、クラス内で定義されているのintタイプ。だから我々は、このようなアプローチを避けなければならない、とクラスの前にメンバーの種類ことを確実にするため。

委託コンストラクタ

C ++ 11には、デリゲートコンストラクタを追加しました。デリゲートコンストラクタそのクラスの使用法、それ他のコンストラクタは、独自の初期化処理を行うか、それはコンストラクタに委ね、自分の(または全ての)他の責任の一部を入れています。一つだけの値デリゲートコンストラクタの初期リストは、他のコンストラクタです。
例えば、次のコードを出力コンストラクトfunc1のコンストラクト関数func2。まず、定義内のデータは、このコンストラクタデリゲートコンストラクタので、第1の呼SALES_DATA(CONST文字列&S、関数func1の出力コンストラクタに委託部分を初期化し、引数なし、関数func2の、すなわち、出力機能とコンストラクタを呼び出す必要があります、int型A)、及びCNT ISBN初期化リストの初期化を使用して、出力メンバ関数は、構築物の関数func1、その後リターンするデリゲートコンストラクタ関数本体、出力コンストラクト関数func2を行います。

class Sales_data
{
public:
	Sales_data(const string &s, int a) :isbn(s), cnt(a) { cout << "construct func1 "; };
	Sales_data() : Sales_data("", 0) { cout << "construct func2 "; }; // 委托构造函数

private:
	string isbn;
	int cnt;
};

int main()
{
	Sales_data data;
}

クラスの暗黙の型変換

コンストラクタは単一の引数を取る場合、それは実際には、暗黙的な変換機構のようなタイプの変換を定義し、時には我々はこのコンストラクタが呼び出された呼び出しの変換コンストラクタ
同様に、上記の例、少し変形を介して、それが変換コンストラクタであるので、一つだけの引数を受け入れることにより、コードSALES_DATA(CONST文字列&S)。したがってSALES_DATAはI =タイプ文字列sのオブジェクトのSALES_DATAタイプでオブジェクトを作成し、私に割り当て正規コンパイラです。
しかし、2段階の変換は許可されていません、私は=などSALES_DATAとして、「123」この文「123」であるのconstのchar *型の、最初の彼はあなたがSALES_DATAが変換コンストラクタでオブジェクトを初期化することができる前に、文字列に変換したいすべての許可されていません。

class Sales_data
{
public:
	Sales_data(const string &s) :isbn(s) {};
private:
	string isbn;
	int cnt = 0;
};

int main()
{
	string s = "123";
	Sales_data i = s;     // 合法
	Sales_data i = "123"; // 非法,不能两步转换
}

また、あなたは使用することができ、明示的な変換を禁止するためのキーワードを。コンストラクタにコードの上になります。

explicit Sales_data(const string &s) :isbn(s) {};

この時点でSALES_DATA iはsが不正です=。ながら、明示的な修飾コンストラクタのみ直接初期化する、すなわちSALES_DATA I(s)は合法です。

リリース6元記事 ウォンの賞賛0 ビュー88

おすすめ

転載: blog.csdn.net/qq_33584870/article/details/104696004