目录
- 一、 再谈构造函数
- 1.1 构造函数体赋值
- 1.2 初始化列表
- 1.3 explicit关键字
- 二、static成员
- 2.1 概念
- 2.2 特性
- 三、友元
- 3.1 友元函数
- 3.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 初始化列表
初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个**"成员变量"后面跟一个放在括号中的初始值或表达式**。
class Date { public: Date(int year, int month, int day) : _year(year) , _month(month) , _day(day) {} private: int _year; int _month; int _day; };
注意:
- 每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)
- 类中包含以下成员,必须放在初始化列表位置进行初始化:
a)引用成员变量
b)const 成员变量
c)自定义类型成员(且该类没有默认构造函数时)
class C { public: C(int c) { _c = c; } private: int _c; }; class CC { public: CC(int ref , int i) :_cc(10) ,_ref(ref) ,_ri(i) {} private: // const 成员变量 const int _ref; // 引用成员变量 int& _ri; // 自定义类型成员(且该类没有默认构造函数时) C _cc; };
- 尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化。
class Time { public: Time(int hour = 0) :_hour(hour) { cout public: Date(int day) {} private: int _day; Time _t; }; int main() { Date d(1); } public: A(int a) :_a1(a) , _a2(_a1) {} void Print() { cout A aa(1); aa.Print(); } public: // 1. 单参构造函数,没有使用explicit修饰,具有类型转换作用 // explicit修饰构造函数,禁止类型转换---explicit去掉之后,代码可以通过编译 explicit Date(int year) :_year(year) {} Date& operator=(const Date& d) { if (this != &d) { _year = d._year; } return *this; } /* // 2. 虽然有多个参数,但是创建对象时后两个参数可以不传递,没有使用explicit修饰,具 有类型转换作用 // explicit修饰构造函数,禁止类型转换 explicit Date(int year, int month = 1, int day = 1) : _year(year) , _month(month) , _day(day) {} Date& operator=(const Date& d) { if (this != &d) { _year = d._year; _month = d._month; _day = d._day; } return *this; }*/ private: int _year; int _month; int _day; }; int main() { Date d1(2022); // 用一个整形变量给日期类型对象赋值 // 实际编译器背后会用2023构造一个无名对象,最后用无名对象给d1对象进行赋值 d1 = 2023; // 将1屏蔽掉,2放开时则编译失败,因为explicit修饰构造函数,禁止了单参构造函数类型转换的作用 return 0; } public: Count() { _sum++; _part++; } Count(const Count& count) { _sum++; _part++; } ~Count() { _part--; } static void Print() { cout Count c1; Count::Print(); Count c2; Count(); Count::Print(); Count c3(c2); Count::Print(); return 0; } public: Date(int year, int month, int day) : _year(year) , _month(month) , _day(day) {} // d1 _cout public: friend ostream& operator } private: int _year; // 年 int _month; // 月 int _day; // 日 }; istream& operator(istream& in, Date& d) { in d._year; in d._month; in d._day; return in; } ostream& operator out Date d1; cin d1; const Date d2(2023, 8, 8); cout public: // 将Date设置为Time的友元,Date中可以直接访问Time的成员变量 friend class Date; public: Time(int hour = 1, int minute = 1, int second = 1) :_hour(hour) ,_minute(minute) ,_second(second) {} private: int _hour; int _minute; int _second; }; class Date { public: Date(int year = 1970, int month = 1, int day = 1) :_year(year) ,_month(month) ,_day(day) ,_t() {} void SetDateTime(int hour = 1, int minute = 1, int second = 1) { _t._hour = hour; _t._minute = minute; _t._second = second; } void Print() { cout Date d(2023, 8, 8); d.Print(); d.SetDateTime(12, 59, 59); d.Print(); return 0; } public: class B // B天生就是A的友元 { public: void foo(const A& a) { cout A::B b; b.foo(A()); return 0; } public: A(int a = 0) :_a(a) { cout cout public: int Sum_Solution(int n) { //... return n; } }; int main() { A aa1; // 不能这么定义对象,因为编译器无法识别下面是一个函数声明,还是对象定义 //A aa1(); // 但是我们可以这么定义匿名对象,匿名对象的特点不用取名字, // 但是他的生命周期只有这一行,我们可以看到下一行他就会自动调用析构函数 A(); A aa2(2); // 匿名对象在这样场景下就很好用,当然还有一些其他使用场景,这个我们以后遇到了再说 Solution().Sum_Solution(10); return 0; } public: A(int a = 0) :_a(a) { cout cout cout _a = aa._a; } return *this; } ~A() { cout } A f2() { A aa; return aa; } int main() { // 传值传参 A aa1; f1(aa1); cout class sum { public: sum() { ref += i; i++; } }; public: int Sum_Solution(int n) { sum a[n]; int sum = ref; return sum; } private: static int i; static int ref; }; int Solution::i = 1; int Solution::ref = 0; int arr[13] = { 0 , 31 , 59 , 90 , 120 , 151 , 181 , 212 , 243 , 273 , 304 , 334 , 365}; if( (month = 2) && (((year % 4 == 0) && (year % 100 != 0))||(year % 400 == 0))) { return arr[month] + 1; } return arr[month]; } int main() { int year = 0 , month = 0 ,day = 0; cin year month day; int getDay = GetMonthDay(year, month - 1) + day; cout int MonthArr[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if ( (month = 2) && (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))) { return 29; } return MonthArr[month]; } int GetYearDay(int year) { if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) { return 366; } return 365; } int DateDif(int date1, int date2) { int max = date1, min = date2; if (max
文章版权声明:除非注明,否则均为VPS857原创文章,转载或复制请以超链接形式并注明出处。
还没有评论,来说两句吧...