论坛门户网站建设运营费用,惠州专业做网站,做海外生意的网站,家装设计网站开发一、再谈构造函数
1.1构造函数体赋值 在创建对象时#xff0c;编译器通过调用构造函数#xff0c;给对象中各个成员变量一个合适的初始值。 class Date
{
public:Date(int year, int month, int day){_year year;_month month;_day day;}private:int _year;int _month;i…一、再谈构造函数
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 A
{
public: A(int a):_a(a){}
private:int _a;
};
class B
{
public: //可以理解为初始化列表是对象的成员变量定义的地方B(int a, int ref):_aobj(a),_ref(ref),_n(10){}
private: //成员变量声明的地方A _aobj; // 没有默认构造函数不用传参就可以调的那个构造函数int _ref; // 引用const int _n; // const
}; 1.3成员变量在类中声明次序就是其在初始化列表中的初始化顺序与其在初始化列表中的先后次序无关
class A
{
public:A(int a):_a1(a) //a赋值给_a1,_a2(_a1) //_a1赋值给_a2{}void Print() {cout_a1 _a2endl;}
private:int _a2; //先声明_a2,再声明_a1int _a1;
};
int main()
{A aa(1); //先把_a1赋值给_a2_a1还没有初始化所以赋值给_a2的是随机值接着1赋值给_a1aa.Print();
}
//输出1 随机值 1.4隐式类型的转换 (explicit关键字 )
class Date
{
public:
//explicit Date(int year) 禁止隐式类型的转换Date(int year): _year(year){}
private:int _year;
};
int main()
{Date d1(1); //构造Date d2 2;//隐式类型的转换构造出tmp(2)再用tmp拷贝构造d2(tmp)优化成直接构造//const Date d2 2; 引用就是中间产生的临时对象Date d3 d1; //拷贝构造return 0;
} explicit 关键字会禁止隐式类型的转换 对于传多个参数针对C11版本 class Date
{
public:Date(int year, int month, int day): _year(year), _month(month), _day(day){}
private:int _year;int _month;int _day;
};
int main()
{Date d1(1,2,3);Date d2 {1,2,3}; //隐式类型转换C11支持return 0;
} 二、 static成员 2.1概念 声明为static的类成员称为类的静态成员用static修饰的成员变量称之为静态成员变量用static修饰的成员函数称之为静态成员函数。静态的成员变量一定要在类外进行初始化。 class A
{
public:
A() {n;}A(const A t) {n;}static int GetACount(); //没有this指针不使用对象就可以调用{ //a 10;//err,不可访问任何非静态成员return n;}
private:int a;static int n; //属于这个类的所有对象也属于这个类
};
int A::n 0; //静态成员变量必须在类外进行定义
void Test()
{A a1, a2;A a3(a1);coutA::GetACount()endl; //不使用对象调用static函数
} 2.2特性 1. 静态成员为所有类对象所共享不属于某个具体的实例 2. 静态成员变量必须在类外定义定义时不添加static关键字 3. 类静态成员即可用类名::静态成员或者对象.静态成员来访问 4. 静态成员函数没有隐藏的this指针不能访问任何非静态成员 5. 静态成员和类的普通成员一样也有public、protected、private3种访问级别也可以具有返回值 2.3问题 1. 静态成员函数可以调用非静态成员函数吗 2. 非静态成员函数可以调用类的静态成员函数吗 class A
{
public:
//1.静态成员函数可以调用非静态成员函数吗
void f1(){}
static void f2()
{f1(); //err没有this指针
}
//2. 非静态成员函数可以调用类的静态成员函数吗
static void f3(){}
void f4()
{f1(); //可以突破类域访问限定符就可以访问。类里面是一个整体都在这个类域中不受访问限定符影响
}
}; 三、C11初始化新玩法 class Date
{
public:Date(){}
void print(){cout_year-_month-_dayendl;}
private://C11才支持,不是初始化是声明时给缺省值int _year 0;int _month 1;int _day 1;//static int n 1; //err,静态成员必须类外面赋值
};四、友元 4.1 友元函数 友元函数可以直接访问类的私有成员它是定义在类外部的普通函数不属于任何类但需要在类的内部声明声明时需要加friend关键字。 class Date
{friend void print(Date d);//突破类的封装
public:Date(int year, int month, int day): _year(year), _month(month), _day(day){}
private:int _year;int _month;int _day;
};
void print(Date d)
{cout d._year - d._month - d._day endl;
}
int main()
{Date d1(1,2,3);print(d1); //调用类外的函数
} 4.2 重载运算符 #include iostream
using namespace std;
class Date
{
public:Date(int year, int month, int day): _year(year), _month(month), _day(day){}void operator(ostream _cout) //this指针占据第一位无法改动{_cout _year - _month - _day;}
private:int _year;int _month;int _day;
};
int main()
{Date d1(1,2,3);//cout d1; //errd1 cout; //d1.operator(cout);有效但没有可读性
} 问题现在我们尝试去重载operator然后发现我们没办法将operator重载成成员函数。因为cout的输出流对象和隐含的this指针在抢占第一个参数的位置。this指针默认是第一个参数也就是左操作数了。但是实际使用中cout需要是第一个形参对象才能正常使用。所以我们要operator重载成全局函数。但是这样的话又会导致类外没办法访问成员那么这里就需要友元来解决。 class Date
{friend ostream operator(ostream _cout, Date d);
public:Date(int year, int month, int day): _year(year), _month(month), _day(day){}
private:int _year;int _month;int _day;
};
ostream operator(ostream _cout,Date d) //类外改变d的位置
{_cout d._year - d._month - d._day endl;return _cout;
}
int main()
{Date d1(1,2,3);Date d2(4, 5, 6);cout d1 d2;
}
实现输入输出
class Date
{friend ostream operator(ostream _cout, const Date d);friend istream operator(istream _cin, Date d);
public:
private:int _year;int _month;int _day;
};
//输出
ostream operator(ostream _cout,const Date d)
{_cout d._year - d._month - d._dayendl;return _cout;
}
//输入
istream operator(istream _cin, Date d) //d中成员要改不加const
{_cin d._year d._month d._day;return _cin;
}
int main()
{Date d1; //调用默认构造函数Date d2;cin d1 d2;cout d1 d2;
} 4.3友元类 友元类的所有成员函数都可以是另一个类的友元函数都可以访问另一个类中的非公有成员。 友元关系是单向的不具有交换性。 比如Time类和Date类在Time类中声明Date类为其友元类那么可以在Date类中直接访问Time 类的私有成员变量但想在Time类中访问Date类中私有的成员变量则不行。 友元关系不能传递如果B是A的友元C是B的友元则不能说明C时A的友元。 class Date; // 前置声明
class Time
{friend class Date; // 声明日期类为时间类的友元类则在日期类中就直接访问Time类中的私有成员变量
public:Time(int hour, int minute, int second): _hour(hour), _minute(minute), _second(second){}
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;
};