cpp module 01

8849 ワード

メモリ割当て(メモリ割当て)、参照(参照)、メンバーへのポインタ.
switch

Memory allocation


C++は、3つの基本タイプのメモリ割り当てをサポートします.
1.静的メモリ割当て(静的メモリ割当て):静的変数とグローバル変数を割り当てます.これらのタイプの変数のメモリは、プログラムの実行時に1回割り当てられ、プログラムのライフサイクル全体で持続します.
2.自動メモリ割り当て(auto memory allocation):関数パラメータと領域変数に対して発生します.これらのタイプの変数のメモリは、関連するブロックを入力するときに割り当てられ、ブロックを終了するときに必要に応じて複数回解放されます.
3.動的メモリ割り当て(Dynamic Memory Allocation):この記事のトピック.
c言語でmalloc、callocでメモリを割り当てる場合は、c++でnewでメモリを割り当てることができます.
形式
::(optional) new (placement_params)(optional) ( type ) initializer(optional
new int(*[10])(); // error: parsed as (new int) (*[10]) ()
new (int (*[10])()); // okay: allocates an array of 10 pointers to functions
double* p = new double[]{1,2,3}; // creates an array of type double[3]
auto p = new auto('c');          // creates a single object of type char. p is a char*
 
auto q = new std::integral auto(1);         // OK: q is a int*
auto q = new std::floating_point auto(true) // ERROR: type constraint not satisfied
 
auto r = new std::pair(1, true); // OK: r is a std::pair<int, bool>*
auto r = new std::vector;        // ERROR: element type can't be deduced
上記のように、再宣言して割り当てることができます.

mallocとnewの違い。

  • mallocは、割り当てるサイズを正しく入れる必要があります.
  • new資料型と初期化する値を加えると、サイズによって割り当てられます.
  • mallocはreallocの機能を有し、再割り当て可能である.newは機能を再割り当てしていません.再割り当てが容易な仕事であればmallocと書きます.
  • newはクラスの作成時にジェネレータ機能を有する.
  • 参照変数


    前回やった.省略

    pointers to members


    c言語に関数アドレスを代入する場合、次のような宣言と使用方法があります.
    void pr(){...}
    
    int main()
    
    {
    
        void(*p)();        // 함수포인터 선언
    
    선언
    #1    p = pr;              // 맞음
    
    #2    p = &pr;            // 맞음
    
    사용
    #1    p()                   // 맞음
    
    #2    (*p)();              // 맞음
    
    }
    このレッスンでは、C++の最初のメンバー関数をポインタとして使用する方法について説明します.
    上で使用したprは一般関数ですが、prがメンバー関数であれば?
    void Tipsware::pr(){...}
    int main()
    {
    	Tipwsware tw;
       void(Tipsware::*p) = &Tipsware::Pr;
       //void(Tipsware::*p) = Tipsware::Pr; // c++에서는 함수 주소를 함수 포인터에 대입할때 &를 생략하는걸 허용하지 않는다. 그래서 에러가 난다고 합니다.
       
       사용
       tw.*p(5); // 이런식으로 사용하면된다. 
    }
    クラスのメンバー関数には、オブジェクトに関係なくアドレスがあります.どのオブジェクトも同じ関数を使用するためです.(コード領域)
    メンバー関数は、オブジェクトの容量を消費しません.コード領域にメモリとして存在します.
    メンバー変数はなく、メンバー関数のみのクラスオブジェクトのサイズは1バイトです.

    このオプションを使用する理由


    構造体と等級の違い。本当によく整理されています

    メンバーオブジェクトcont

    class X {
    private:
      int a;
    public:
      void f(int b) {
    		a = b;
      }
      void s(int b) const {
    		a = b;
      }
    };
    Xというクラスには、fという関数とsという関数があります.
    2つの関数の違いはconstです.
    二つの違いは何ですか.
    ご存じのように、クラスメンバーオブジェクトはthisポインタを省略します.
    public:
      void f(int b) {
    		this->a = b;
      }
    このように、上記のf関数にはthisが含まれています.ただし、s関数の場合、contが後に追加されます.これは、thisをcontタイプとして使用することを意味します.
    だからs関数人は、
      void s(int b) const {
    		this->a = b;
    ただし、constなので値は変換できません.そのため、上のコードでエラーが発生しました.

    継承


    継承が必要な理由.
    class test
    {
    	private :
       	int tmp;
       public :
       	void play(int parm_data)
           {
           	tmp = parm_data;
           }
    }
    
    class test2
    {
    	private :
       	int tmp;
       public :
       	void play(int parm_data)
           {
           	if(parm_data < 0) parm_data = parm_data * - 1;
           	tmp = parm_data;
           }
    }
    
    void main ()
    {
    	test a;
       test2 a2;
       
       a.play(-1);
       a2.play(-1);
    }
    上のようにプレイは重複する部分が多いコードですが、それを変えるためには新しいクラスを作成する必要があります.
    test 2にtestのプレイを読み込んで使用します.
    これらの重複コードを最大限に減らすために,cppには継承の概念がある.
     class test
     {
     	protected :
        	int tmp;
        public :
        	void paly(int parm_data)
            {
            	tmp = parm_data;
            }
     }
     
     class test2 : public test
     {
        public :
        	void paly(int parm_data)
            {
            	if(parm_data < 0) parm_data = parm_data * - 1;
                  test::play(parm_data);
            }
     }
     
     void main ()
     {
     	test a;
        test2 a2;
        
        a.play(-1);
        a2.play(-1);
     }
    上から見るとtest 2 クラス宣言時:public testが追加されました.これにより、共通データを継承して使用できます.
    その後、test 2では同じ関数を作成する必要はなく、親関数を呼び出す限り、同じコードを記述する必要はありません.(test::play(parm_data);)
    クラスにはpublic、private、protectedの3つのアクセス権者があります.
    publicとprotectedは、継承された子供から親に訪問することができます.
    privateは子供から親に近づくことができない.
    protectedとprivateの残りの仕事は同じです.
    publicが子供として受け継がれれば、保護された性格で受け継がれる.

    引き継ぐ。


    画像ソース


    継承時に継承権の範囲を制限し、どのように継承するかを制限できます.
     class test
     {
     	private:
        	int tmp1;
     	protected :
        	int tmp2;
    	public :
        	int tmp3
    }
     
     class test2 : public test
     {
     	tmp1 = 1; //private는  상속에서 사용불가.
        tmp2 = 1; // protected 는 protected로 사용가능
        tmp3 = 1; // public 는 public로 사용가능
        }
     class test
     {
     	private:
        	int tmp1;
     	protected :
        	int tmp2;
    	public :
        	int tmp3
    }
     
     class test2 : protected test
     {
     	tmp1 = 1; //private는  상속에서 사용불가.
        tmp2 = 1; // protected 는 protected로 사용가능
        tmp3 = 1; // public 는 protected로 사용가능
     }
     class test
    {
    	private:
       	int tmp1;
    	protected :
       	int tmp2;
    	public :
       	int tmp3
    }
    
    class test2 : private test
    {
    	tmp1 = 1; //private는  상속에서 사용불가.
       tmp2 = 1; // protected 는 private로 사용가능
       tmp3 = 1; // public 는 private로 사용가능

    switch

      switch(x)
      {
      	case 0:
      		cout << "Zero";
      	case 1:
      		cout << "One";
      	case 2:
      		cout << "Two";
    このように使用できるのは、switch文はそのうちの1つを実行してif~else文を終了するのではなく、case 0を実行してもcase 2と比較し、マッチングがあれば追加の実行がなければ終了する点に注意してください.

    動的割当ての例

    Zombie *first = new Zombie[N];
    N個のZombiデータ型を生成します.
    拭いた時.
    delete [] first;

    参照とポインタの違い。

      5     std::string str;
      6     str = "HI THIS IS BRAIN";
      7     std::string *stringPTR = &str;
      8     std::string &stringREF = str;
    どちらの方法もstringPTR、stringREFにアドレスを配置しますが、使用方法が異なり、stringPTRは独自のアドレスを格納する必要があります.

    初期化リスト

      3 HumanA::HumanA ( std::string name, Weapon &club ) : C(club)
      4 {
      5     HumanA::name = name;
      6 }
    「:C(club)」タイプの作成者では、初期化リストを使用して、「:C(club)」タイプの作成者でインスタンスを作成する場合は、(club)形式でCを作成できます.
    初期化リストの例

    iostream, ofstream


    Input file stream:ファイルから何でも入力できるクラスです.
    Out file stream:ファイルに任意の内容を入力するクラスです.
    このクラスのオブジェクトは、内部ストリームバッファとしてファイルバッファを使用し、リンクされたファイル(ある場合)に対して入出力操作を実行します.
    https://www.cplusplus.com/reference/fstream/ifstream/?kw=ifstream

    if文を持たない条件処理

     28 void    karen::complain( std::string level )
     29 {
     30     void    (karen::*exec_func)(void);
     31
     32     exec_func = &karen::nothing;
     33     (!level.compare("DEBUG") && (exec_func = &karen::debug));
     34     (!level.compare("INFO") && (exec_func = &karen::info));
     35     (!level.compare("WARNING") && (exec_func = &karen::warning));
     36     (!level.compare("ERROR") && (exec_func = &karen::error));
     37     (this->*exec_func)();
     38 }
    なぜ課題にこんなことがあるのでしょうか.よくわかりませんが…いずれにしても,文がない場合,このようにcompare関数により比較と操作を行った.

    switch case

     21     switch(i)
     22     {
     23         case 4:
     24             std::cout << "[ Probably complaining about insignificant     problems ]" << std::endl;
     25             break;
     26         case 0:
     27             test.complain( "DEBUG" );
     28         case 1:
     29             test.complain( "INFO" );
     30         case 2:
     31             test.complain( "WARNING" );
     32         case 3:
     33             test.complain( "ERROR" );
     34     }
    以上のように,switch文を用いてif文とは少し異なる方法で条件を扱うことを習得した.