类和对象(8):explicit,static成员,友元,内部类

简介: 类和对象(8):explicit,static成员,友元,内部类

一、explicit

class Date
{
public:
  Date(int year = 2023, int month = 1, int day = 1)
    :_year(year)
    ,_month(month)
    ,_day(day)
  {}

private:
  int _year;
  int _month;
  int _day;
};


int main()
{
    // Date d1(1); // 这是正常初始化
  Date d1 = 1;

  return 0;
}

不妨猜测一下,d1的初始化结果是什么?

构造函数不仅可以构造与初始化对象,对于1. 单个参数 2. 全缺省 3. 除第一个参数无默认值外其余均有默认值的构造函数,还具有类型转换的作用。

explicit修饰构造函数,将会禁止构造函数的默认转换。

二、static成员

2.1 概念

声明为static的类成员,称为类的静态成员(静态成员变量或静态成员函数)静态成员变量一定要在类外初始化

class A
{
private:
  static int _a;// 声明
};

int _a = 0;// 初始化

2.2 特性

  1. 静态成员所有类对象共享,存在静态区。
  2. 静态成员变量必须在类外初始化,初始化时不加static
  3. 类静态成员可用**类名::静态成员** 或 **对象.静态成员**来访问。
class A
{
public:
  static int GetCount_top()
  {
    _top++;
    return _top;
  }

  A()
    :_a1(1)
  {}

private:
  int _a1;
  static int _top;
};

int A::_top = 0;

int main()
{
  A a1;
  cout << a1.GetCount_top() << endl; // 对象.静态成员
    cout << A().GetCount_top() << endl;
    // A() 为匿名对象
  cout << A::GetCount_top() << endl; // 类名::静态成员

  return 0;
}

A() 为匿名对象,当前语句结束后自动销毁。

  1. 类静态成员函数没有隐藏的this指针,不能访问任何非静态成员
  2. 静态成员也是类的成员,同样受访问限定符的限制
int main()
{
  A a1;
  cout << a1._top << endl; // error C2248: “A::_top”: 无法访问 private 成员(在“A”类中声明)

  return 0;
}

三、友元

友元是一种突破封装的方式,部分场景能提供便利。但友元会增加耦合度,不宜多用。

3.1 友元函数
class Date
{
public:
  Date(int year = 1900, int month = 1, int day = 1)
    :_year(year)
    , _month(month)
    , _day(day)
  {}

  friend ostream& operator<<(ostream& out, const Date& d); // 友元函数
  friend istream& operator>>(istream& in, Date& d);

private:
  int _year;
  int _month;
  int _day;
};

ostream& operator<<(ostream& out, const Date& d)
{
  out << d._year << "-" << d._month << "-" << d._day;
  return out;
}

istream& operator>>(istream& in, Date& d)
{
  in >> d._year >> d._month >> d._day;
  return in;
}

友元函数可以直接访问类的私有成员,它是定义在类外部的函数,不是类的成员函数;需要在类的内部声明,声明时加friend

PS:

  1. 友元函数不能用const修饰
  2. 友元函数可以在类定义的任何位置声明,不受访问限定符限制
  3. 一个函数可以是多个类的友元函数。
  4. 友元函数的调用与普通函数相同。
3.2 友元类

友元类的所有成员函数,都是另一个类的友元函数,可以访问另一类的私有成员。

  1. 友元关系是单向的,不具备交换性。
class A
{
    friend class B;// B是A的友元类,但A不是B的友元类
public:
  A()
    :_a(1)
    {}
private:
  int _a;
};

class B
{
public:
  B()
    :_b(1)
  {
    A a1;
  }
private:
  int _b;
};

int main()
{
  B b1;
  return 0;
}
  1. 友元关系不能传递

B是A的友元,C是B的友元,但C和A没有友元关系。

四、内部类

4.1 概念

存在类A、B,如果B定义在A的内部,B称为A的内部类

内部类是一个独立的类,不属于外部类不能通过外部类的对象访问内部类的成员

PS: 内部类就是外部类的友元类,外部类不是内部类的友元。

4.2 特性
  1. 内部类可以定义在外部类的任何位置。
  2. 内部类可以直接访问外部类static成员,不需要使用外部类的 类名对象
  3. sizeof(外部类)=外部类,与内部类无关
相关文章
|
2月前
|
存储 编译器 C++
【C++】深入探索类和对象:初始化列表及其static成员与友元(一)
【C++】深入探索类和对象:初始化列表及其static成员与友元
|
2月前
|
C++
【C++】深入探索类和对象:初始化列表及其static成员与友元(二)
【C++】深入探索类和对象:初始化列表及其static成员与友元
|
2月前
|
编译器 C++
【C++】深入探索类和对象:初始化列表及其static成员与友元(三)
【C++】深入探索类和对象:初始化列表及其static成员与友元
|
7月前
|
存储 算法 C语言
【C++入门到精通】C++入门 —— 类和对象(初始化列表、Static成员、友元、内部类、匿名对象)
一、初始化列表 ⭕初始化列表概念 ⭕初始化列表的优点 ⭕使用场景 ⭕explicit关键字 二、Static成员 ⭕Static成员概念 🔴静态数据成员: 🔴静态函数成员: ⭕使用静态成员的
115 0
|
5月前
|
编译器 C++
【C++】类和对象⑤(static成员 | 友元 | 内部类 | 匿名对象)
📚 C++ 知识点概览:探索类的`static`成员、友元及应用🔍。
|
7月前
|
编译器 C++
【C++】类与对象(static、explicit、友元、隐式类型转换、内部类、匿名对象)
【C++】类与对象(static、explicit、友元、隐式类型转换、内部类、匿名对象)
36 2
|
7月前
|
存储 Java C++
【C++类和对象】探索static成员、友元以及内部类
【C++类和对象】探索static成员、友元以及内部类
|
算法 C++
【C++入门到精通】C++入门 —— 类和对象(初始化列表、Static成员、友元、内部类、匿名对象)下
【C++入门到精通】C++入门 —— 类和对象(初始化列表、Static成员、友元、内部类、匿名对象)下
82 0
【C++入门到精通】C++入门 —— 类和对象(初始化列表、Static成员、友元、内部类、匿名对象)下
|
7月前
|
C++
C++——类和对象(初始化列表、匿名对象、static成员、类的隐式类型转换和explicit关键字、内部类)
C++——类和对象(初始化列表、匿名对象、static成员、类的隐式类型转换和explicit关键字、内部类)
|
编译器 C++
C++类和对象下(初始化列表,静态成员,explicit关键字,友元)(上)
C++类和对象下(初始化列表,静态成员,explicit关键字,友元)