匿名对象
格式:类名();
作用:
- 用匿名对象给有名对象初始化
- 用匿名对象初始化对象数组
#include <iostream>
using namespace std;
class Dog
{
private:
string name;
int age;
public:
Dog()
{
}
Dog(string n,int a):name(n),age(a)
{
}
void show()
{
cout << name << " " << age << endl;
}
};
void fun(Dog d)
{
}
int main()
{
Dog("black",3); //匿名对象
Dog d1 = Dog("yellow",5);
d1.show();
Dog d[4] = {Dog("blue",2),Dog("red",1),Dog("ming",5)};
d[2].show();
return 0;
}
友元
作用:让一些函数或一些类,去访问另一个类的私有属性。
种类:全局函数作友元,类作友元,成员函数作友元
关键字:friend
全局函数作友元
让全局函数访问一个类的私有数据成员
#include <iostream>
using namespace std;
class Room
{
friend void godgay(Room &r); //说明godgay函数为该类的友元
private:
string bedroom;
public:
string livingroom;
Room(string b,string l):bedroom(b),livingroom(l)
{
}
};
void godgay(Room &r)
{
cout << r.livingroom << endl;
cout << r.bedroom << endl;
}
int main()
{
Room r("正在访问卧室","正在访问客厅");
godgay(r);
return 0;
}
类作友元
让一个类去访问另一个类的私有属性
#include <iostream>
using namespace std;
//声明room类
class Room;
class Friend
{
private:
Room *R;
public:
Friend();
void visit();
};
class Room
{
friend class Friend; //声明Friend类为该类的友元,Friend类可以访问该类的私有数据成员
private:
string bedroom;
public:
string livingroom;
Room(string b,string l):bedroom(b),livingroom(l)
{
}
};
Friend::Friend()
{
R = new Room("卧室","客厅");
}
void Friend::visit()
{
cout << " 正在访问:" << R->bedroom << endl;
cout << " 正在访问:" << R->livingroom << endl;
}
int main()
{
Friend f;
f.visit();
return 0;
}
成员函数作友元(了解)
结论
- 不要滥用友元,会降低封装性。
- 友元不具有交互性,传递性,继承性。
常成员函数和常对象(const)
类中所有的成员函数都可以对数据成员做修改操作,如果设计一个成员函数不能对数据成员做修改,则需要使用常成员函数。
常成员函数
常成员函数的不能修改数据成员的值
常对象
常对象:常对象表示该对象的数据成员不可改变
格式:const 类名 对象名;
#include <iostream>
using namespace std;
//封装类
class Stu
{
private:
string name;
int age;
public:
Stu()
{
}
Stu(string n,int a):name(n),age(a)
{
}
void show() const //常成员函数
{
//age = 28; 错误,常成员函数不能修改数据成员的值
cout << "name= " << name << endl;
cout << "age= " << age << endl;
}
void show() //非常成员函数
{
age = 28;
cout << "name= " << name << endl;
cout << "age= " << age << endl;
}
};
int main()
{
Stu s("zhang",18); //非常对象
const Stu s1("zhang",18); //常对象
s.show();
s1.show();
return 0;
}
注意:
- 非常对象可以调用常成员函数也可以调用非常成员函数,优先调用非常成员函数
- 常对象只能调用常成员函数
运算符重载
运算符重载就是对运算符重新定义,赋予另一种功能,以适应不同的数据类型
*每个运算符都有两种实现版本:
- 成员函数实现运算符重载
- 全局函数实现运算符重载
算数运算符重载
种类:+,-,*,/,%
表达式:左操作数 运算符 右操作数
左操作数:可以是左值,也可以是右值,运算过程中不能被改变。
右操作数:可以是左值,也可以是右值,运算过程中不能被改变。
结果:只能是右值(不能被改变)。
成员函数实现算数运算符重载
const 类名 operator运算符 (const 类名 &右操作数) const
{
}
第一个const:表示运算结果不可改变
第二个const:控制右操作数不能被改变
第三个const:控制左操作数不能被改变
#include <iostream>
using namespace std;
//封装类
class Stu
{
private:
int a;
int b;
public:
Stu()
{
}
Stu(int a,int b):a(a),b(b)
{
}
void show()
{
cout << "a= " << a << endl;
cout << "b= " << b << endl;
}
//成员函数实现算术运算符重载
const Stu operator+(const Stu &right) const
{
Stu temp;
temp.a = a + right.a;
temp.b = b + right.b;
return temp;
}
};
int main()
{
Stu s1(2,3);
Stu s2(4,5);
Stu s3 = s1 + s2;
s3.show();
return 0;
}
全局函数实现算数运算符重载
const 类名 operator运算符 (const 类名 &左操作数,const 类名 &右操作数)
{
}
#include <iostream>
using namespace std;
//封装类
class Stu
{
friend const Stu operator+(const Stu &left,const Stu &right); //需要创建友元使得全局函数可以访问类的私有数据成员
private:
int a;
int b;
public:
Stu()
{
}
Stu(int a,int b):a(a),b(b)
{
}
void show()
{
cout << "a= " << a << endl;
cout << "b= " << b << endl;
}
};
//全局函数实现算术运算符重载
const Stu operator+(const Stu &left,const Stu &right)
{
Stu temp;
temp.a = left.a + right.a;
temp.b = left.b + right.b;
return temp;
}
int main()
{
Stu s1(2,3);
Stu s2(4,5);
Stu s3 = s1 + s2;
s3.show();
return 0;
}
练习:
实现算数运算符的重载
#include <iostream>
using namespace std;
//封装类
class Stu
{
friend const Stu operator+(const Stu &left,const Stu &right);
friend const Stu operator*(const Stu &left,const Stu &right);
private:
int a;
int b;
public:
Stu()
{
}
Stu(int a,int b):a(a),b(b)
{
}
void show()
{
cout << "a= " << a << endl;
cout << "b= " << b << endl;
}
//成员函数实现"-"重载
const Stu operator-(const Stu &right) const
{
Stu temp;
temp.a = a - right.a;
temp.b = b - right.b;
return temp;
}
};
//全局函数实现"+"重载
const Stu operator+(const Stu &left,const Stu &right)
{
Stu temp;
temp.a = left.a + right.a;
temp.b = left.b + right.b;
return temp;
}
//全局函数实现"*"重载
const Stu operator*(const Stu &left,const Stu &right)
{
Stu temp;
temp.a = left.a * right.a;
temp.b = left.b * right.b;
return temp;
}
int main()
{
Stu s1(2,3);
Stu s2(4,5);
Stu s3 = s1 + s2;
Stu s4 = s1 - s2;
Stu s5 = s3 * s4;
s3.show();
s4.show();
s5.show();
return 0;
}