私有构造函数
首先,private成员与方法只能被类内部的方法访问,而protected成员与方法只能被类内部或派生类内部的方法访问。
而构造函数一定是在外部被访问,所以含有private或protected构造函数的类不能声明对象。
我觉得这种类常用于抽象类,即含有纯虚函数的类,这种类用于实现多态,只能从其子类声明对象,为了防止用抽象类声明对象,将其构造函数设为私有。
派生类的构造函数调用
既然抽象类不能声明对象,那么其构造函数还有什么意义呢?
回忆起子类声明的过程,构造函数是一层层向上调用的,所以最终会调用抽象基类的构造函数,用来初始化抽象基类的成员。单例模式
private构造函数还有一个重要的用法为实现简单单例模式:
1
2
3
4
5
6
7
8
9
10
11
12
13class CSingleton{
private:
CSingleton(){//构造函数是私有的
}
static CSingleton *m_pInstance;
public:
static CSingleton * GetInstance(){
if(m_pInstance == NULL) //判断是否第一次调用
m_pInstance = new CSingleton();
return m_pInstance;
}
};用户获得实例的方法只有通过
GetInstance
方法:1
2CSingleton * pCSingle = CSingleton::GetInstance();
CSingleton * p2 = pCSingle->GetInstance();
类的static
成员
首先,static
关键字的作用有二:
- 当它用在全局变量上时,它的作用是限制该变量的可见范围,将该变量限制在本文件内可见;
- 当它应用在局部变量上时,会将该变量的存储位置改变为存储在静态区,并且将该变量的生存周期改为整个程序都存在,虽然变量的作用域不发生变化。
类中定义的static
成员,同样存储在静态存储区,类的所有对象共用static
成员,既保证了对外部隐藏,即作用于仅限于类内部,又实现了所有类对象之间的共享。
- 对于
static
函数,其没有this指针,不能访问类的普通成员与成员函数,只能访问类的静态成员; - 对于
static
成员,需要在定义时初始化,且不能在头文件中初始化,初始化方法为:<数据类型><类名>::<静态数据成员名>=<值>
; - 对于
public
类型的static
成员,可用<类名>::<静态成员名>
的方法在非类的对象中引用静态成员,进一步说明了静态成员属于类而非对象; - 子类和父类的同名
static
成员或方法,调用哪一个看作用域。
虚函数调用
今天对虚函数的调用有疑问,主要疑问为:类方法对虚函数的调用到底调用的是哪个。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32class A{
public:
virtual int go_out(){
cout << "out A" << endl;
return 0;
}
};
class B:public A{
public:
int test(){
go_out();
return 0;
}
int go_out(){
cout << "out B" << endl;
return 0;
}
};
class C:public B{
int go_out(){
cout << "out C" <<endl;
return 0;
}
};
int main(int argc, char **argv){
C *cc = new C();
cc->test();
return 0;
}
实验发现,输出结果为out C
。
其实这符合虚函数的调用原理,毕竟test是通过指向C类型的指针调用的。
改为B *cc = new C();
输出结果也一样。