【C++练级之路】【Lv.4】类和对象(下)(初始化列表,友元,static成员,编译器的优化)

2024-02-26 1512阅读

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

目录

  • 一、再谈构造函数
    • 1.1 构造函数体赋值
    • 1.2 初始化列表
    • 1.3 explicit关键字
    • 二、static成员
      • 2.1 概念
      • 2.2 特性
      • 三、友元
        • 3.1 引入
        • 3.2 友元函数
          • 3.2.1 概念
          • 3.2.2 特性
          • 3.3 友元类
            • 3.3.1 概念
            • 3.3.2 特性
            • 四、内部类
              • 4.1 概念
              • 4.2 特性
              • 五、匿名对象
              • 六、编译器的优化
                • 6.1 传参优化
                  • 6.1.1 传值传参
                  • 6.1.2 传引用传参
                  • 6.2 返回优化
                    • 6.2.1 创建对象再返回
                    • 6.2.2 返回匿名对象
                    • 6.3 优化总结
                      • 6.3.1 函数传参
                      • 6.3.2 对象返回
                      • 七、再次理解封装
                      • 总结

                        欢迎各位小伙伴关注我的专栏,和我一起系统学习C++,共同探讨和进步哦!

                        学习专栏:

                        《进击的C++》

                        一、再谈构造函数

                        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 初始化列表

                        那么,成员变量到底是在什么地方初始化的呢?其实,在构造函数的初始化列表里。

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

                        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. 类中包含以下成员,必须放在初始化列表位置进行初始化:
                          • 引用成员变量
                          • const成员变量
                          • 自定义类型成员(且该类没有默认构造函数时)
                        class Time
                        {
                        public:
                        	Time(int hour)
                        		: _hour(hour)
                        	{}
                        private:
                        	int _hour;
                        };
                        class Date
                        {
                        public:
                        	Date(int year, int month, int day)
                        		: _year(year)
                        		, _month(month)
                        		, _day(day)
                        		, _t(10)
                        	{}
                        private:
                        	int _year;
                        	const int _month;//const
                        	int& _day;//引用
                        	Time _t;//没有默认构造函数
                        };
                        
                        1. 无论是否显式使用初始化列表,成员变量都在初始化列表定义。所以,尽量使用初始化列表初始化。
                        2. 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关。

                        请思考下面代码的运行结果:

                        class A
                        {
                        public:
                            A(int a)
                               : _a1(a)
                               , _a2(_a1)
                            {}
                            void Print()
                            {
                                cout
                            A aa(1);
                            aa.Print();
                        }
                        A. 输出1  1 
                        B.程序崩溃
                        C.编译不通过
                        D.输出1  随机值
                        
                        public:
                        	Time(int hour)
                        		: _hour(hour)
                        	{}
                        private:
                        	int _hour;
                        };
                        int main()
                        {
                        	Time t1(4);
                        	Time t2 = 4;
                        	return 0;
                        }
                        
                        public:
                        	Time(int hour, int minute)
                        		: _hour(hour)
                        		, _minute(minute)
                        	{}
                        private:
                        	int _hour;
                        	int _minute;
                        };
                        int main()
                        {
                        	Time t1(4, 5);
                        	Time t2 = { 4,5 };
                        	return 0;
                        }
                        
                        public:
                        	explicit Time(int hour)
                        		: _hour(hour)
                        	{}
                        	explicit Time(int hour, int minute)
                        	: _hour(hour)
                        	, _minute(minute)
                        	{}
                        private:
                        	int _hour;
                        	int _minute;
                        };
                        int main()
                        {
                        	Time t1(4);
                        	Time t2 = 4;//err
                        	Time t3(4, 5);
                        	Time t4 = { 4,5 };//err
                        	return 0;
                        }
                        
                        public:
                        	A(int a = 4)
                        		: _a(a)
                        	{
                        		++count;
                        	}
                        	A(const A& a)
                        		: _a(a._a)
                        	{
                        		++count;
                        	}
                        private:
                        	int _a;
                        };
                        int main()
                        {
                        	A a1;
                        	A a2 = 5;
                        	A a3(3);
                        	cout 
                        	A a1;
                        	A a2 = 5;
                        	A a3(3);
                        	++count;
                        	++count;
                        	
                        	cout 
                        public:
                        	A(int a = 4)
                        		: _a(a)
                        	{
                        		++count;
                        	}
                        	A(const A& a)
                        		: _a(a._a)
                        	{
                        		++count;
                        	}
                        	static int GetCount()//静态成员函数
                        	{
                        		return count;
                        	}
                        private:
                        	int _a;
                        	static int count;//静态成员声明
                        };
                        int A::count = 0;//静态成员定义
                        int main()
                        {
                        	A a1;
                        	A a2 = 5;
                        	A a3(3);
                        	cout 
                        public:
                        	Date(int year = 2000, int month = 1, int day = 1)
                        		: _year(year)
                        		, _month(month)
                        		, _day(day)
                        	{}
                        	ostream& operator
                        		out 
                        		in  _year  _month  _day;
                        		return in;
                        	}
                        private:
                        	int _year;
                        	int _month;
                        	int _day;
                        };
                        int main()
                        {
                        	Date d;
                        	d  cin;//不符合常规写法逻辑
                        	d 
                        	friend ostream& operator}
                        private:
                        	int _year;
                        	int _month;
                        	int _day;
                        };
                        ostream& operator
                        	out 
                        	in  d._year  d._month  d._day;
                        	return in;
                        }
                        int main()
                        {
                        	Date d;
                        	cin  d;
                        	cout 
                        	friend class Date;//友元类
                        public:
                        	Time(int hour = 0, int minute = 0, int second = 0)
                        		: _hour(hour)
                        		, _minute(minute)
                        		, _second(second)
                        	{}
                        	void Print()
                        	{}
                        private:
                        	int _hour;
                        	int _minute;
                        	int _second;
                        };
                        class Date
                        {
                        public:
                        	Date(int year = 1900, int month = 1, int day = 1)
                        		: _year(year)
                        		, _month(month)
                        		, _day(day)
                        	{}
                        	void SetTimeOfDate(int hour, int minute, int second)
                        	{
                        		// 直接访问时间类私有的成员变量
                        		_t._hour = hour;
                        		_t._minute = minute;
                        		_t._second = second;
                        	}
                        private:
                        	int _year;
                        	int _month;
                        	int _day;
                        	Time _t;
                        };
                        
                        private:
                        	static int k;
                        	int h;
                        public:
                        	class B // B天生就是A的友元
                        	{
                        	public:
                        		void foo(const A& a)
                        		{
                        			cout 
                            A::B b;
                            b.foo(A());//传参A的匿名对象
                            
                            return 0;
                        }
                        
                        public:
                        	int Sum_Solution(int n)
                        	{
                        		//...
                        		return n;
                        	}
                        };
                        int main()
                        {
                        	// 匿名对象在这样场景下就很好用,当然还有一些其他使用场景,这个我们以后遇到了再说
                        	cout 
                        public:
                        	A(int a = 1)
                        		: _a(a)
                        	{
                        		cout 
                        		cout 
                        		cout 
                        			_a = a._a;
                        		}
                        		return *this;
                        	}
                        	~A()
                        	{
                        		cout }
                        int main()
                        {
                        	A a1 = 1;//构造+拷贝构造——》优化为构造
                        	f1(a1);//无优化,只能在同一表达式进行优化
                        	f1(2);//构造+拷贝构造——》优化为构造
                        	f1(A(3));//构造+拷贝构造——》优化为构造
                        	return 0;
                        }
                        }
                        int main()
                        {
                        	A a1 = 1;//构造+拷贝构造——》优化为构造
                        	f2(a1);//无优化
                        	f2(2);//无优化
                        	f2(A(3));//无优化
                        	return 0;
                        }
                        
                        	A a;
                        	return a;
                        }
                        int main()
                        {
                        	f3();//无优化,因为在不同表达式
                        	A a1 = f3();//构造+两次拷贝构造——》优化为构造+拷贝构造
                        	A a3;
                        	a3 = f3();//思考这种写法与上述写法的区别
                        	return 0;
                        }
                        
                        	return A();
                        }
                        int main()
                        {
                        	f4();//构造+拷贝构造——》优化为构造
                        	A a2 = f4();//构造+两次拷贝构造——》优化为构造
                        	return 0;
                        }
                        
VPS购买请点击我

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

目录[+]