1. 程式人生 > >C++建構函式是否可以定義為private

C++建構函式是否可以定義為private

思考下:什麼時候建構函式需要定義為private?

1,如果一個類的建構函式只有一個且為private,這是可以編譯通過的;

class Parent
{
private :
    Parent()
    {
        cout<<"parent :private"<<endl;
    }
};

2,如果一個類的建構函式只有一個且是private,如果類的內部沒有專門建立例項的程式碼,則是無法建立任何例項的;

class Parent
{
private :
    Parent()
    {
        cout<<"parent :private"<<endl;
    }
};

int main()

{

  Parent parent=new Parent();

}

則此程式無法執行

3,如果一個類的建構函式只有一個且是private,如果類的內部有專門建立例項的程式碼,則只能建立一個或多個例項(根據類內部宣告的成員物件個數來定)

class Parent
{

private:

static Parent * parent1;

static Parent * parent2;
    Parent()
    {
        cout<<"parent :private"<<endl;
    }

  static Parent*  GetInstace1()

  {

     if(parent1!=NULL)

     return parent1;

else

     parent1=new Parent();

    return parent1;

  }

  static Parent*  GetInstace2()

  {

     if(parent12=NULL)

     return parent2;

else

     parent2=new Parent();

    return parent2;

  }


};

Parent * Parent::parent1;

Parent * Parent::parent2;

int main()

{

  Parent *parent=Parent::GetInstance1();

}

這樣就可以得到一個例項parent1,或者呼叫GetInstance2()得到另外一個例項;

此處注意:靜態成員變數必須要定義,要初始化;即在內部宣告之後,外部必須要初始化。

3,如果一個類的建構函式不止一個,如果其中有一個為Private而且也有引數  例如:private: Parent(int val){}外部初始化時必須要加引數  例如 Parent * Parent::parent(3);

4,如果一個類的建構函式不止一個,private 建構函式如果引數 為void(無參),則子類無法編譯;換言之,如果一個類建構函式只有private且存在子類,則無法編譯,除非父類建構函式為public。

#include<iostream>
using namespace std;

class Parent
{
private :
    static Parent p1;
    static Parent p2;
    Parent(int val)
    {
        cout<<"CONSTRTCTOR  Private(int val) function in  class PARENT Start :"<<endl;
        cout<<"parent :private"<<endl;
        cout<<"CONSTRTCTOR  Private(int val) function in  class PARENT End :"<<endl;
    }

    void Test(void)
    {
        cout<<"Test() function in  class PARENT Start :"<<endl;
        cout<<"Test"<<endl;
        cout<<"Test() function in  class PARENT End :"<<endl;
    }
public  :
    Parent()
    {
        cout<<"CONSTRTCTOR  Public(int val) function in  class PARENT Start :"<<endl;
        cout<<"parent :public now and here"<<endl;
        cout<<"CONSTRTCTOR  Public(int val) function in  class PARENT End :"<<endl;
    }

    static Parent* GetInstance_1(int val);
    static Parent  GetInstance_2(int val)
    {
        if(&p2!=NULL)
        {
            cout<<"p2:"<<&p2<<endl;
            return p2;
        }
        p2=*(new Parent(val));
        cout<<"p2:"<<&p2<<endl;
        return p2;
    }

    static Parent& GetInstance_3(int val)
    {
        if(&p1!=NULL)
        {
            cout<<"p1:"<<&p1<<endl;
            return p1;
        }
        p1=*(new Parent(val));
        cout<<"p1:"<<&p1<<endl;

        return p1;
    }

    void print(void)
    {
        cout<<"Print() function in  class PARENT Start :"<<endl;
        cout<<"p1:"<<&p1<<endl;
        cout<<"p2:"<<&p2<<endl;
        Test();
        cout<<"Print() function in  class PARENT End :"<<endl;
    }

};
Parent Parent::p1;
Parent Parent::p2;
Parent*  Parent::GetInstance_1(int val)
{
    if(&p1!=NULL)
    {
        cout<<"p1:"<<&p1<<endl;
        return &p1;
    }
    p1=*(new Parent(val));
    return &p1;
}

class Child : public  Parent
{
private :
    static Child child_1;
    Child(int val)
    {
        cout<<"CONSTRTCTOR  Private(int val) function in  class CHILID Start :"<<endl;
        cout<<"child "<<endl;
        cout<<"CONSTRTCTOR  Private(int val) function in  class CHILID End :"<<endl;
    }

    void Test(void)
    {
        cout<<"Test private function in  class CHILID Start :"<<endl;
        cout<<"test child"<<endl;
        cout<<"Test private function in  class CHILID Start :"<<endl;
    }

public:
    Child(){}

    static Child & GetInstance()
    {
        return child_1;
    }

    static Child  GetInstance_origin()
    {
        return child_1;
    }
    void print()
    {
        Test();
    }

};

Child Child::child_1;


class A
{
private:
    static A m_ins;
public:
    static A* GetInstance();
private:
    A()    
    {
        cout<<"private A() has been motived"<<endl;
    }
};

A A::m_ins;

A* A::GetInstance()
{
    cout<<"GetInstance"<<&m_ins<<endl;
    if(&m_ins!=NULL)
    {
        cout<<"good"<<endl;
    }
    else
    {
        cout<<"bad"<<endl;
        m_ins= *(new A());
        cout<<"new A() \n the addr of m_ins is "<<&m_ins<<endl;
    }
    return &m_ins;
};

int main()
{
    A *a=A::GetInstance();
    cout<<"In main the addr of A * a ="<<a<<endl;
    Parent * parent1=Parent::GetInstance_1(2);
    parent1->print();
    //Parent* parent1=Parent::GetInstance_1(4);
    /*Parent parent2=Parent::GetInstance_2(5);
    Parent& parent3=Parent::GetInstance_3(6);
    */
    Child child=Child::GetInstance();
    return 0;
}

現在解決開始的問題:當建構函式是private主要是想讓類中存在一個公共的類物件,也許是唯一的一個也許是共享的一個

note:

1,void可以作為函式定義形引數但是不可以作為呼叫引數;

2,類的內部呼叫完全無阻礙,不管任何保護型別都可以互相呼叫;但是static 成員函式不可以呼叫非static成員函式;換言之,public private protected是訪問型別,而static是儲存型別。

3,   類內部自身的例項成員一般為static,否則難以建立成功,會預設為int;這個比較費解,建議專門花時間理解。

4,如果一個有非空返回型別,但是函式體內部為空,則會得到一個空;編譯可以通過,呼叫有問題;

5,類內成員函式 在內部定義和在外部定義的差別 ???類內部成員變數在內部定義和外部定義的差別; static 成員在類內部是宣告,在外部是定義。

6,當你的Student繼承自某個類,而這個類沒有預設建構函式(包括類成員無預設構造),你就不得不用這種語法(subClass():parentclass())了,這個時候就不能放在大括號裡了。一個類的建構函式加冒號跟 "a資料成員的建構函式 "或者 "b父類的建構函式"。