一 基本概念
1.类是数据类型,是结构概念的推广。
2.声明语法:class 类名;
3.定义语法:
class 类名{
private: 成员声明 | 定义;
public: 成员声明 | 定义;
protected: 成员声明 | 定义;
};
成员函数的定义:
在类体内(为inline函数): 值类型 函数名(形参表) 函数体
在类体外(必须在类内声明): 值类型 类名::函数名(形参表) 函数体
public区的内容是类的接口。
1.构造函数:用于初始化对象。
定义语法:
类名(形参表) 函数体
2.拷贝构造函数:用于按照一个对象构造另一个对象。
浅拷贝,会导致以下问题:
(1)公用指针指向的空间;
(2)析构时free会出问题(多次释放同一空间)。
深拷贝,自己写。
缺省的拷贝构造函数:
类名(const 类名 & 形参名) 函数体
调用的时机:
a.用一个对象初始化另一个对象;
b.形参为类类型时,参数传递;
c.返回类类型的对象。
3.析构函数:对象退出生存期时自动调用。
定义语法:
~类名() 函数体
二 对象(类类型的变量)
定义语法:
类名 变量名; //类中有默认构造函数
类名 变量名 = 表达式; //有一元构造函数
类名 变量名 = 构造函数(实参表);
类名 变量名(实参表); //实参表不能为空
推荐使用:第1种和第4种。例如:
#include <iostream>
using namespace std;
class A
{
private:
int x;
public:
A(int x = 0){
this->x = x;
}
void f(){
x = x + 1;
}
int g(){
return x;
}
};
int main()
{
A a = 1;
a.f();
cout << a.g() << endl;
A b = A(2);
b.f();
cout << b.g() << endl;
A c(3);
c.f();
cout << c.g() << endl;
A d;
d.f();
cout << d.g() << endl;
return 0;
}
1.每个对象各有一套自己的数据成员,所有对象共享一套成员函数。
2.成员的引用:
对象名.数据成员
对象名.成员函数(实参表)
3.this指针
每个成员函数,都有一个隐含的参数,名为this,类型为指向该类的指针,值为当前对象的地址。
4.访问权限
公有成员可在程序的任何地方访问;私有,保护成员只能在类内使用。
这里的类内指的是类体 && 类外定义的诸成员函数名至定义尾。
三 const对象和const成员函数
const对象
定义语法: const 类名 对象名(实参表);
const成员函数:不修改数据成员的成员函数,明确声明为const。
定义语法: 值类型 函数名(形参表) const 函数体
四 静态成员
静态数据成员:所有对象共享的数据成员
声明语法:static 类型名 成员名;
定义语法:类型名 类名::成员名 = 初始表达式;
静态成员函数:只引用静态数据成员的函数,声明为静态的(没有this指针)
定义语法:static 函数定义
调用:类名.成员函数(实参表);类名.成员
五 嵌套类(内部类)
在类内声明的类。例子如下:
#include <iostream>
using namespace std;
class C
{
private:
int x;
void f_c(){
cout << "private fun in C is called!" << endl;
}
public:
class B{
private:
int y;
void f_b(){
cout << "B's private fun is called!" << endl;
}
public:
void fun_B(C c){
c.f_c();
cout << "C's private data: " << c.x << endl;
}
B(int y){
this->y = y;
}
};
C(int x){
this->x = x;
}
void fun_C(B b){
//error C2248: 'C::B::y' :
//cannot access private member declared in class 'C::B'
//cout << "B's private data:" << b.y << endl;
//error C2248: 'C::B::f_b' :
//cannot access private member declared in class 'C::B'
//b.f_b();
}
};
int main()
{
C c(5);
C::B b(3);
b.fun_B(c);
c.fun_C(b);
return 0;
}
程序输出:
private fun in C is called!
C's private data: 5
可见,内部类可以访问外部类的私有变量和私有函数;但是外部类不能访问内部类的私有成员,这与private的可见范围是一致的。
内部类用于两个逻辑上组成关系的类,例如:链表类与节点类;容器类与迭代子类等。
六 友元
不是类的成员,但是可以访问类的私有成员。
定义语法:
friend class 类名;
friend 类名::成员函数名(形参表);
friend 函数名(形参表); // 全局函数
以上可出现在任意区中(private, public, protected)。
<补充>
如果不主动编写拷贝构造函数和拷贝构造函数,编译器将以“按位”拷贝的方式自动生成相应的默认函数。如果类中含有指针成员或者引用成员,那么这两个默认的函数就隐含了错误。
例如:
String a("hello");
String b("world");
String c = a; // 调用拷贝构造函数,最好写成c(a);
c = b; // 调用赋值函数
拷贝构造函数和拷贝赋值函数很容易混淆,拷贝构造函数是在对象备创建并用另一个已经存在的对象来初始化它时调用的,而赋值函数只能把一个对象赋值给另一个已经存在的对象。