特殊なC++クラスの作成

25974 ワード

1ヒープでのみ作成できるクラスを作成する
  スタックでのみ作成できるクラスの基本構想は、スタックでの作成に失敗させることです.スタック上でクラスプログラムを作成するには、コンストラクタとアナライザを呼び出してクラスオブジェクトを初期化および破棄する必要があります.プログラムに構造関数と構造関数を呼び出すのに失敗した実装は、構造関数をprivateまたはprotectedとして宣言することである.
1.1構造関数と構造関数はすべて私有ですか?
最も直接的な書き方は、構造関数と構造関数を私有化し、また、スタック上に関連するオブジェクトポインタのみを作成するオブジェクト作成インタフェースを作成することです.
class test
{
private:
    test(){}
    ~test(){}
    
public:
    static test* create_instance()
    {
        return new test;
    }

    static void delete_instance(test **ptr)
    {
        delete *ptr;
        *ptr = nullptr;
    }
};


int main() {
    test test_instance;             //    ,           
    test *ptr = test::create_instance();
    test::delete_instance(&ptr);
    if(ptr == nullptr)
    {
        cout<<"    "<<endl;
    }
}

  は完全に構造関数のみを私有化することができる.このような利点は、newオペレータによってオブジェクトのポインタを作成することができ、newを再ロードして追加の操作を行う必要がある場合、最初の方法で完全に操作することができることです.この方式は最小の修正に基づいて目的地を達成する原則に基づいて改善される.
#include 
#include 

using namespace std;

class test
{
public:
    test(){}
    
private:
    ~test(){}
    
public:
    static test* create_instance()
    {
        return new test;
    }

    static void delete_instance(test **ptr)
    {
        delete *ptr;
        *ptr = nullptr;
    }
};


int main() {
    //test test_instance;             //    ,           
    test *ptr = test::create_instance();
    test *new_ptr = new test;
    test::delete_instance(&ptr);
    test::delete_instance(&new_ptr);
    if(ptr == nullptr && nullptr == new_ptr)
    {
        cout<<"    "<<endl;
    }
}

  もちろん、コンストラクション関数のみをプライベート化しても、deleteを使用してオブジェクトを削除できます.
#include 
#include 

using namespace std;

class test
{
private:
    test(){}
    
public:
    ~test(){}
    
public:
    static test* create_instance()
    {
        return new test;
    }

    static void delete_instance(test **ptr)
    {
        delete *ptr;
        *ptr = nullptr;
    }
};


int main() {
    //test test_instance;             //    ,           
    test *ptr = test::create_instance();
    test::delete_instance(&ptr);
    if(ptr == nullptr )
    {
        cout<<"    "<<endl;
    }
}

  注意しなければならないのは、以上の3つの方法の違いです.
  • 構造解析はすべて私有化されている:オブジェクトはスタックにしか存在せず、スタックに存在するオブジェクトは現在のクラスの関連関数にしか生存できない.
  • は私有化のみを構築する:厳密には現在の関数によってスタック上のオブジェクトを取得することができる.析構は私有ではなく、効果的に破棄することができるからである.
  • は、オブジェクトがスタック上にのみ存在し、スタック上に存在するオブジェクトが現在のクラスの関連関数内にのみ存在するプライベート化のみを解析します.

  • 1.2 privateですか、protectedですか.
     priavteとprotectedの違いは継承にある.作成したクラスを継承する必要がある場合、privateを使用すると、子クラスが親クラスを呼び出すことができないコンストラクション関数を使用して親クラスを構築し、作成に失敗したり、クラスのコンストラクション関数を呼び出すことができなくなったりして、破棄に失敗します.protectedを使用する場合、継承システムの外部では、まだ分離する権限があり、スタック上のオブジェクトしか作成できません.
    #include 
    #include 
    
    using namespace std;
    
    class test
    {
    public:
        test(){}
        
    protected:
        ~test(){}
        
    public:
        static test* create_instance()
        {
            return new test;
        }
    
        static void delete_instance(test **ptr)
        {
            delete *ptr;
            *ptr = nullptr;
        }
    };
    
    class driverd_test : public test
    {
    public:
        driverd_test(){}
        
    protected:
        ~driverd_test(){}
        
        static driverd_test* create_instance()
        {
            return new driverd_test;
        }
    
        static void delete_instance(driverd_test **ptr)
        {
            delete *ptr;
            *ptr = nullptr;
        }
    };
    
    int main() {
        //test test_instance;             //    ,           
        test *ptr = test::create_instance();
        test::delete_instance(&ptr);
        if(ptr == nullptr )
        {
            cout<

      protectedprivateの違いを使用することに注意してください.
  • private:スタック上のオブジェクトは現在のクラスにのみ存在します.
  • protected:スタック上のオブジェクトは現在の継承システムに存在することができる.

  • 2スタックでのみ作成できるクラスを作成する
    スタック上でのみ作成できるオブジェクトの基本原則は、スタック上でのオブジェクトの作成に失敗することです.
    2.1独占構造ルート
      は、上述したようにコンストラクション関数をプライベート化し、カスタム静的関数によってクラスオブジェクトを取得することができる.
    class test
    {
    private:
        test(){};
        
        
    public:
        static test get_object()
        {
            return test();
        }
    };
    

    2.2 newとdeleteオペレータの呼び出しを禁止する
      は、operator newおよびoperator deleteをプライベート化またはprotectedすることによってアクセス権を制御する.
    class test
    {
    private:
        void* operator new(size_t size);
        void operator delete(void* p);
     
        void* operator new[](size_t size);
        void operator delete[](void* p);
        
    public:
        static test get_object()
        {
            return test();
        }
    };
    
    int main() {
        //test test_instance;             //    ,           
       test a;
       test *p = new test;                  //    
    }
    

      は、operator newおよびoperator deletedeleteとして明示することによってアクセスを制限する.
    #include 
    #include 
    
    using namespace std;
    
    class test
    {
    public:
        void* operator new(size_t size) = delete;
        void operator delete(void* p) = delete;
     
        void* operator new[](size_t size) = delete;
        void operator delete[](void* p) = delete;
        
    public:
        static test get_object()
        {
            return test();
        }
    };
    
    int main() {
        //test test_instance;             //    ,           
       test a;
       test *p = new test;                  //    
    }
    

    3継承できないクラスの作成
    継承できないクラスを作成する基本原理は、アクセス制御です.現在のクラスは継承できませんが、クラスのすべての特性を含める必要があります.そのため、現在のクラスでは手足を動かすことはできません.構造関数と構造関数をプライベートに設定し、現在のクラスのみがアクセスできる不要なクラスを宣言できます.これにより、他のクラスが現在のクラスを継承する場合、ベースクラスの構造関数を呼び出す必要がありますが、権限がないため継承に失敗します. このうちgrad_fatherクラスは継承に失敗した.
    #include 
    #include 
    
    using namespace std;
    
    class child
    {
        friend class father;
    private:
        child(){};
        ~child(){};
    };
    
    class father : virtual public child
    {
    
    };
    
    //    
    class grad_father : public father
    {
    public:
        grad_father(){};
        ~grad_father();
    };
    
    int main() {
        father f;
        grad_father ff;
    }
    

      もう1つの簡単な実装方法は、キーワードfinalを介して:
    class base final{};
    
    class derived : public base{};          //