思考下:什么时候构造函数需要定义为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父类的构造函数"。