【C++】类与对象(四)——初始化列表|explicit关键字|static成员|友元|匿名对象

2024-02-26 1235阅读

温馨提示:这篇文章已超过438天没有更新,请注意相关的内容是否还可用!

【C++】类与对象(四)——初始化列表|explicit关键字|static成员|友元|匿名对象

前言:

初始化列表,explicit关键字,static成员,友元,匿名对象


文章目录

  • 一、构造函数的初始化列表
    • 1.1 构造函数体内赋值
    • 1.2 初始化列表
    • 二、explicit关键字
    • 三、static成员
    • 四、友元
      • 4.1 友元函数
      • 4.2 友元类
      • 五、内部类
      • 六、匿名对象

        一、构造函数的初始化列表

        1.1 构造函数体内赋值

        class Date{
        public:
        	Date(int year, int month, int day){
        		//赋值,并非初始化
        		_year = year;
        		_month = month;
        		_day = day;
        	}
        private:
        	int _year;
        	int _month;
        	int _day;
        };
        

        构造函数调用之后,在函数体中给成员变量赋值,但这并不能称为初始化,因为初始化是在变量或对象的创建时进行的,如果有初始化,那么仅有一次只有一次,而构造函数体内可以多次赋值。

        对于某些类型的成员变量,必须进行初始化。函数体内并不能满足这些类型的成员变量进行初始化,因此有了初始化列表的概念。


        1.2 初始化列表

        初始化列表用于在构造函数中初始化类成员变量的语法结构:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。

        _year _month _day被year,month,day进行初始化

        Date(int year, int month, int day) :
        		_year(year), 
        		_month(month), 
        		_day(day) {
        		//函数体内其他操作
        }	
        
        1. 实际上,即使没有显式写出初始化列表,成员变量依然会走初始化列表,但是因为没有初始值,因此成员变量是默认值。且初始化列表的顺序是成员变量声明的顺序。

          【C++】类与对象(四)——初始化列表|explicit关键字|static成员|友元|匿名对象

        2. 以下成员,必须放在初始化列表位置进行初始化

          • 引用成员变量
          • const成员变量
          • 自定义类型成员(且该类没有默认构造函数时)
            class A{
            public:
            	A(int a):_a(a){
            	}
            private:
            	int _a;
            };
            class B{
            private:
            	A _aobj;      // 自定义类型且没有默认构造函数
            	int& _ref;    // 引用
            	const int _n; // const 
            public:
            	// _aobj(a)可以理解为调用A类的构造函数
            	B(int a, int ref):_aobj(a), _ref(ref), _n(0){
            		// 其他操作
            	}
            };
            int main() {               
            	B b(10,5);
            	return 0;
            }
            
          • 成员变量声明时提供缺值

            当成员变量没有在初始化列表初始化时,成员变量被默认初始化为缺省值。

            class Date{
            public:
            	Date(int year, int month, int day) :
            		_month(month),
            		_day(day) {
            		//函数体内其他操作
            	}
            private:
            	int _year = 1;
            	int _month;
            	int _day;
            };
            int main() {
            	//B b();
            	Date d(2024, 1, 31);
            	return 0;
            }
            

            【C++】类与对象(四)——初始化列表|explicit关键字|static成员|友元|匿名对象

        通常初始化列表与构造函数体内赋值混合使用。


        二、explicit关键字

        1. 单参数构造函数可以支持隐式类型的转换。

          意思是允许通过给定类型的单一参数将对象从一种类型转换为另一种类型,而无需显式调用构造函数。

          class Distance {
          private:
              double meters;
          public:
              // 单参数构造函数,允许从 double 类型隐式转换为 Distance 类型
              Distance(double m) : meters(m) {}  
          };
          int main() {
              // 隐式类型转换:double 到 Distance
              Distance d1 = 10.5;
              // 显式类型转换也是可行的
              Distance d2 = Distance(15.2);
              return 0;
          }
          

          在这个例子中,Distance 类具有一个单参数构造函数,允许将 double 类型的值隐式转换为 Distance 类型。当我们使用 Distance d1 = 10.5; 时,编译器会自动调用单参数构造函数,将 10.5 隐式转换为 Distance 类型的对象 d1。

        2. C++11及之后的标准中,引入了一种新的特性,即“允许多参数的构造函数用于隐式类型转换”

          例如:

          class MyClass {
          public:
              // 多参数的构造函数
              MyClass(int x, double y) {
                  // 构造函数逻辑
                  std::cout 
              // 隐式类型转换,调用构造函数
              MyClass obj = {42, 3.14};
              return 0;
          }
          }
          
          public:
              // 构造函数,用于增加 count
              MyClass() {
                  count++;
              }
              int& GetCount() {
                  return count;
              }
          private:
              // 静态数据成员
              static int count;
          };
          // 初始化静态数据成员
          int MyClass::count = 0;
          int main() {
              // 创建对象,增加 count
              MyClass obj1;
              MyClass obj2;
              // 访问静态数据成员
              std::cout 
          public:
              // 静态成员函数,用于加法运算
              static int add(int a, int b) {
                  return a + b;
              }
          };
          int main() {
              // 调用静态成员函数
              int result = MathOperations::add(3, 5);
              std::cout 
          private:
              int privateData;
          public:
              MyClass(int data) : privateData(data) {}
              // 声明友元函数
              friend void displayPrivateData(const MyClass&);
          };
          // 定义友元函数
          void displayPrivateData(const MyClass& obj) {
              std::cout 
              MyClass obj(42);
              displayPrivateData(obj); // 友元函数可以访问私有成员
              return 0;
          }
          
          private:
              int privateMember;
              // 将 FriendClass 声明为友元类
              friend class FriendClass;
          public:
              MyClass(int data) : privateMember(data) {}
          };
          class FriendClass {
          public:
              void accessPrivateMember(const MyClass& obj) {
                  // 友元类可以访问 MyClass 的私有成员
                  int data = obj.privateMember;
              }
          };
          int main() {
              MyClass a(10);
              FriendClass b;
              b.accessPrivateMember(a);
              return 0;
          }
          
          private:
              int outerPrivate;
          public:
              class Inner {
              public:
                  void display(const Outer& outer) {
                      std::cout }
              void callInner() {
                  Inner inner;
                  inner.display(*this);
              }
          };
          int main() {
              //通过callInner调用display
              Outer outerObj(42);
              outerObj.callInner();
              //创建inner对象调用display
              Outer::Inner innerObj;
              innerObj.display(outerObj);
              return 0;
          }
          
          public:
              void display() {
                  std::cout 
              // 创建匿名对象,并调用其成员函数
              MyClass().display();
              
              return 0;
          }
          
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]