类的成员

一个类包含:

  • 变量
  • 函数
  • 构造函数
  • 析构函数

内联成员函数 inline

使用inline关键字将函数声明为内联函数。

**作用:**在编译阶段内联函数会将函数体替换到函数调用处,也就是说内联函数省去了调用函数花费的时间。

声明方法:

  • 类内声明 直接在类内声明函数体会将函数隐式的声明为内联函数。
1
2
3
4
5
6
7
class A{
public:
//隐式地声明为内联函数
void func(){
std::cout<<"Call Function"<<std::endl;
}
}
  • 类外声明 类外声明的函数使用inline关键字将函数声明为内联函数。
1
2
3
4
5
6
7
8
class A{
public:
void func();
}
//显式地声明为内联函数
inline void A::func(){
std::cout<<"Call Function"<<std::endl;
}

注意要点:

  • 递归函数不能声明为内联函数。
  • 函数体过大的函数不建议声明为内联函数
  • 函数体中有switch语句for循环等不建议声明为内联函数

类与结构体

类与结构体几乎没有什么区别。
唯一的区别是类的默认访问限制符是private,结构体是public。

访问限制符

  • private
  • protected
  • public

构造函数与析构函数

构造函数

实例化对象时调用

复制构造函数

  • 定义一个对象时,以本类另一个对象作为初始值,发生复制构造;将一个对象赋值给另一个对象。
  • 如果函数的形参是类的对象,调用函数时,将使用实参对象初始化形参对象,发生复制构造;形实结合。
  • 如果函数的返回值是类的对象,函数执行完成返回主调函数时,将使用return语句中的对象初始化一个临时无名对象,传递给主调函数,此时发生复制构造。返回对象给主调函数

委托构造函数

使用类内已经声明的构造函数。
类中往往有多个构造函数,只是参数表和初始化列表不同,其初始化算法都是相同的,这时为了避免代码重复,可以使用委托构造函数。

析构函数

删除对象时调用

前向引用声明

什么时候使用前向声明:

  • 类应该先声明,后使用。
  • 如果需要在某个类的声明之前,引用该类,则应进行前向引用声明。
  • 前向引用声明只为程序引入一个标识符,但具体声明在其他地方。

需要注意的是:

  • 使用前向引用声明虽然可以解决一些问题,但它并不是万能的。
  • 在提供一个完整的类声明之前,不能声明该类的对象,也不能在内联成员函数中使用该类的对象。
  • 当使用前向引用声明时,只能使用被声明的符号,而不能涉及类的任何细节。
1
2
3
4
5
6
7
8
9
class Fred; //前向引用声明
class Barney
{
Fred x; //错误:类Fred的声明尚不完善
};
class Fred
{
Barney y;
};

但可以这样做:

1
2
3
4
5
6
7
8
9
class Fred;
class Barney
{
Fred* x;
};
class Fred
{
Barney* y;
};

主要是因为指针的大小是确定的。使用指向未知对象的指针不影响类的占用空间。

静态成员 static

友元

friend 关键字可以用于修饰函数和类,即友元函数、友元类。

友元函数

友元函数可以在函数体中通过对象名访问其private和protected成员。

**作用:**增加灵活性,使程序员可以在封装和快速性方面做合理选择。

友元类

若一个类为另一个类的友元,则此类的所有成员都能访问对方类的私有成员。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class A 
{
friend class B;
public:
void display() {cout<<x<<endl;}
private:
int x;
}

class B
{
public:
void set(int i);
void display();
private:
A a;
};

void B::set(int i)
{
a.x=i; //B是A的友元,所以在B的成员函数中可以访问A类对象的私有成员。
}
void B::display() {a.display();}

友元的注意事项

类的友元关系是单向不可传递不能被继承

  • 单向:如果声明B类是A类的友元,B类的成员函数就可以访问A类的私有和保护数据,但A类的成员函数却不能访问B类的私有、保护数据。
  • 不可传递:B类是A类的友元,C类是B类的友元,C类和A类如果没声明,就没有友元关系。
  • 不能继承:类B是类A的友元,类B的派生类不会自动的成为类A的友元。45