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父類的建構函式"。