「C++Primer」オブジェクト、配列、オブジェクトベース設計、汎用設計


はいれつ
C++は配列をサポートしない抽象abstractionも配列全体の操作をサポートしない場合があります.例えば、配列全体を操作したい場合があります.例えば、1つの配列を別の配列に割り当てて2つの配列を等しく比較したり、配列のサイズを知りたい場合があります.例えば、2つの配列を与えたりします.私たちは、割り当てオペレータで1つの配列を別の配列にコピーすることはできません.
int array0[ 10 ], array1[ 10 ];
array0 = array1;  //error
配列タイプ自体は自己意識がなく、自分の長さを知らないので、配列自体の情報を別途記録しなければなりません.
配列とポインタの関係:
int ia[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21 };
ia; 何を意味しますか.配列識別子は、配列内の最初の要素のアドレスを表します.そのタイプは、配列要素タイプのポインタです.
ia; 等価&ia[0];
*(ia+1); 等価ia[1];
オブジェクトの作成
*1つ目は、クラスを直接定義するインスタンスです.オブジェクト:
CGoods Car;
この定義はCGoodsクラスのオブジェクトCarを作成し、データを格納し、これらのデータに対して操作を実行するメンバー関数(コード)を割り当てます.変数定義と同様に、1つのオブジェクトは定義されたドメインでのみ有効です.
*2つ目は、クラスのオブジェクトを動的に作成する方法です.
ダイナミックメモリ割り当て(Dynamic Memory Allocation)は、配列の大容量化などの静的コンパイルでは解決できない問題を解決することができる.
C/C++は4つのメモリ区間:1)、コード領域、2)、グローバル変数と静的変数領域、3)、ローカル変数領域すなわちスタック領域、4)、動的記憶領域、すなわちスタック(heap)領域またはフリー記憶領域を定義する.
静的割当てと動的割当て:
一般に変数(またはオブジェクト)を定義し、コンパイラはコンパイル時にその変数(またはオブジェクト)のタイプに基づいて必要なメモリ領域の大きさを知ることができ、システムは適切な時に決定されたメモリ領域を割り当てることができる.このメモリ割り当てを静的ストレージ割り当てと呼ぶ.
一部のオペレーティングオブジェクトは、プログラムの実行時にのみ決定され、コンパイル時に記憶領域を予約できないため、プログラムの実行時にのみ、システムが要求に応じてメモリ割り当てを行う方法を動的記憶割り当てと呼びます.
すべてのダイナミックストレージ割り当ては、スタック領域で行われます.プログラムが動的に割り当てられた変数またはオブジェクトを必要とするまで実行される場合、その変数またはオブジェクトを格納するために、スタック内の必要なサイズの格納空間をシステムに申請する必要があります.変数またはオブジェクトが使用されなくなった場合、つまりそのライフが終了した場合、使用されたストレージスペースを明示的に解放することで、システムはスタックスペースを再割り当てし、限られたリソースを繰り返し使用することができます.動的割当てフォーマット:
ポインタ変数名=newタイプ名(初期化式);
deleteポインタ名;
eg:
 int  *pi=new int(0); 
delete pi;//なお、piが指すターゲットメモリ領域は解放されたが、piポインタ自体は取り消されず、このポインタが占めるメモリ領域は解放されなかった.
説明:
*new演算子は、割り当てられたタイプの変数(オブジェクト)を指すポインタを返します.作成された変数またはオブジェクトは、そのポインタによって間接的に操作されますが、動的に作成されたオブジェクト自体には名前がありません.
*一般的に変数とオブジェクトを定義するときは、識別子で名前を付けます.名前付きオブジェクトと呼ばれますが、動的な名前のないオブジェクトと呼ばれます(スタック内の一時オブジェクトとは異なり、ライフサイクルが異なり、操作方法が異なり、一時変数はプログラマに対して透過的であることに注意してください).
*ヒープ領域は、割り当て時に自動初期化(ゼロクリアを含む)されず、初期化式(initializer)で明示的に初期化する必要があります.
*new式の動作シーケンスは、スタック領域からオブジェクトを割り当て、カッコ内の値でオブジェクトを初期化します.オブジェクトベースの設計
配列抽象化を実現し、
1.配列クラスの実装には、まず自分の大きさを知る自己意識が組み込まれている.
2.配列クラスは、配列間の割り当てと、2つの配列間の等しい比較操作と等しくない比較操作をサポートします.
3.配列クラスは、その値に含まれる次のクエリをサポートする必要があります.配列の最小値がどの最大値であるか、特定の値が配列に存在する場合、その最初の位置のインデックスが何であるかをクエリーします.
4.配列クラスは自己ソートをサポートする議論を容易にするために、配列がソートをサポートする機能が重要であると考えているユーザーが存在すると仮定するために、他の一部の人は、配列操作をサポートするだけでなく、配列自体をサポートしなければならないメカニズムが含まれているとは思わない.
5.コンパイル時に知る必要のない長さを指定して配列を作成できます.
6.配列は、値のセットで初期化できます.
7.配列内の単一要素に1つのインデックスでアクセスすることができ、議論を容易にするために、ユーザが配列の下付きオペレータでこの機能を実現することを強く要求すると仮定する.
8.誤ったインデックス値をキャプチャし、指摘することができる仮定は、必要であると考えているので、ユーザーの考えを尋ねることはありません.これは、良好な配列を設計するために実現しなければならないと考えています.潜在的なユーザーとの議論は、大きな熱を呼んでいます.
IntArray.h
class IntArray
{
private :
	int _size; //    
	int *p;   //    

public:
	IntArray(int array_size);
	IntArray(int *array,int array_size);
	IntArray(IntArray &arr);//      
	~IntArray();
	void sort(); //  
	int find(int value);//  
	int max();//    
	int min();//    
	int size();//    
	void display();
};

IntArray.cpp
#include  //io     
#include "IntArray.h"
using namespace std;

/************************************************************************/
/*               
          0
*/
/************************************************************************/
IntArray::IntArray(int array_size)
{
	_size = array_size;
	p = new int[array_size];
	for (int i = 0; i max) {
			max = p[i];
		}
	}
	return max;
}

/************************************************************************/
/*                                                                             */
/************************************************************************/
int IntArray::min()
{
	int min = 10000;
	for (int i = 0; i<_size i="" if="" min="" return="" int="" intarray::find="" value="" index="-1;" for="" intarray::size="" _size="" void="" intarray::display="" cout="" or="" intarray::sort="" intarray::="" delete="" p="" main="" inta="" intarray="" intarr="" intarr.size="" intarr.min="" intarr.find="" intarr.display="" intarr.=""/>

汎用設計(generic programming)
IntArrayクラスは、定義済みの整数配列タイプに有用な代替タイプを提供します.ユーザーがdoubleまたはstringタイプの配列を使用したい場合は、
キーワードtemplate導入テンプレートパラメータは、カッコ<>で囲まれています.
template < class elemType >
class Array {
public:
Array( int size );
Array( elemType *array, int array_size );
virtual elemType min() ;
virtual elemType max() ;
private:
int _size;
elemType *ia;
};
以降、instantiateの特定のタイプのインスタンスをインスタンス化すると、int doubleやstringタイプのArray配列のような3つのインスタンスをプログラムで直接使用することができる.
呼び出し:
const int array_size = 4;
//elemTypeがintになりました
Array ia(array_size);
//elemTypeがdoubleになりました
Array da(array_size);
//elemTypeがcharになりました
Array ca(array_size);
クラステンプレートのメンバー関数はどうなりますか.すべてのメンバー関数がクラステンプレートのインスタンス化に伴って自動的にインスタンス化されるわけではありません.プログラムによって使用されるメンバー関数だけがインスタンス化されます.これは、プログラム生成中の独立した段階で一般的に発生します.