1、static关键字
tool.cpp
#include<iostream>
using namespace std;
static int a = 100;//1. 限定全局变量只能在本文件使用
static void fun()//2. 限定函数只能在本文件使用
{
cout << "fun" << endl;
}
main.cpp
#include<iostream>
using namespace std;
void fun2()
{
static int n = 0;//3. 静态存储区的变量,只初始化一次,生命周期为整个程序期间
cout << ++n << endl;
}
class A //4.修饰成员变量和函数,使其变成静态的成员,属于所有对象公有的
{
public:
//静态成员函数
static void print()
{
cout << "静态成员函数!" << endl;
}
private:
static int a;//静态成员变量
};
int main()
{
extern int a;//只是声明
//cout << a << endl;
extern void fun();//函数的声明
//fun();
//fun2调用3次
fun2();
fun2();
fun2();
//用类名调用静态方法
A::print();
return 0;
}
静态成员变量:
- 静态成员变量可以实现多个对象之间的数据共享,它是类的所有对象的共享成员,它在内存中只占一份空间,如果改变它的值,则各个对象这个数据成员的值都被改变。
- 静态成员变量是在程序开始运行时分配空间,到程序结束之后才释放,只要类中指定了静态成员变量,即使不定义对象,也会为静态成员变量分配空间。
#include<iostream>
using namespace std;
class A
{
public:
A()
{
++count;//每产生一个对象,引用计数加1
}
void print()
{
cout << "此时共产生了" << count << "个对象!" << endl;
}
//静态成员函数
static void print2()
{
//静态成员函数无法访问非静态成员变量
//cout << a << endl;//错误
cout <<"静态成员函数:"<< count << endl;
}
public:
static int count;
//static int count = 0; 错误
int a;
};
//静态成员变量只能在类外初始化,并且加上A::前缀
int A::count = 0;
int main()
{
A a;
a.print();
A b;
a.print();
b.print();
A c;
a.print();
b.print();
b.print();
//两种访问公有静态成员变量的方式 A:: 对象.
cout << A::count << endl;
cout << a.count << endl;
//两种访问公有静态成员函数的方式 A:: 对象.
A::print2();
a.print2();
return 0;
}
2、继承与派生
类的继承,是新的类从已有类那里得到已有的特性,或从已有类产生新类的过程就是类的派生。原来的类称为基类或者父类,产生的新类称为派生类或者子类。
子类、派生类的声明:
class 派生类名: 继承方式 基类名1
{
派生类成员声明;
};
派生类继承基类中除了构造函数和析构函数以外的所有成员。
//父类
class A
{
public:
A()
{
a = 100;
}
void print()
{
cout << "A::print()" << endl;
}
int a;
};
//子类
class B : public A
{
};
int main()
{
B b;
cout << b.a << endl;//使用父类的成员变量
b.print();//使用父类的成员函数
return 0;
}
派生类中由基类继承而来的成员的初始化工作还是由基类的构造函数完成,然后派生类中新增的成员在派生类的构造函数中初始化。
构造函数的调用顺序
父类的构造函数 ~> 子类的构造函数
class A
{
public:
A(int a)
{
this->a = a;
cout << "A的带参数构造函数!" << endl;
}
void print()
{
cout << this->a << endl;
}
private :
int a;
};
class B: public A
{
public:
//构造父类需要在初始化构造列表里实现
B(int b, int a): A(a)
{
this->b = b;
cout << "B的带参构造函数!" << endl;
}
void print()
{
A::print();//明确的指出调用A的print,或者两个名字取不同的
cout << b << endl;
}
private:
int b;
};
int main()
{
//先有父亲,再有儿子, 先构造父类,再构造子类
B b(222,111);
b.print();
return 0;
}
析构函数的调用顺序
子类的析构函数 ~> 父类的析构函数
class A
{
public:
A()
{
this->pA = new int[10];
cout << "A的构造函数!" << endl;
}
~A()
{
delete []pA; //做内存释放清理工作
this->pA = NULL;
cout << "A的析构函数!" << endl;
}
private:
int *pA;
};
class B : public A
{
public:
B()
{
this->pB = new int[10];
cout << "B的构造函数!" << endl;
}
~B()
{
delete []pB; //做内存释放清理工作
this->pB = NULL;
cout << "B的析构函数!" << endl;
}
private:
int *pB;
};
int main()
{
//析构和构造的顺序正好相反
B b;
return 0;
}
C++允许多重继承,Java只允许单继承
多重继承的构造函数
父类的构造函数(按继承的顺序依次执行) ~> 子类的构造函数
class A
{
public:
A(int a)
{
cout << "A构造函数!" << endl;
this->a = a;
}
public:
int a;
};
class B
{
public:
B(int b)
{
cout << "B构造函数!" << endl;
this->b = b;
}
public:
int b;
};
class C : public A, public B //这里AB顺序决定构造顺序
{
public:
//用初始化列表构造父类带参数的构造函数
C(int a, int b, int c) : A(a), B(b)//这里AB顺序无所谓
{
cout << "C构造函数!" << endl;
this->c = c;
}
public:
int c;
};
int main()
{
C c(111, 222, 333);
cout << c.a << " " << c.b << " " << c.c << endl;
return 0;
}
多重继承的析构函数
class A
{
public:
A()
{
cout << "A构造函数!" << endl;
}
~A()
{
cout << "A析构函数!" << endl;
}
};
class B
{
public:
B()
{
cout << "B构造函数!" << endl;
}
~B()
{
cout << "B析构函数!" << endl;
}
};
class C : public A, public B //按继承顺序来
{
public:
C()
{
cout << "C构造函数!" << endl;
}
~C()
{
cout << "C析构函数!" << endl;
}
};
int main()
{
// 析构函数的顺序总与构造顺序相反
C c;
return 0;
}