Part 1.梳理思维导图
一.匿名对象
1.概念
没有对象名的类对象
2.格式
类名();
3.作用
1.给有名对象初始化
2.给对象数组初始化
3.作为函数的参数传递给形参
4.例子
#include <iostream>
using namespace std;
class Dog
{
friend void Dogfriend(Dog &b);
private:
string name;
int age;
public:
Dog()
{
}
Dog(string name,int age):name(name),age(age)
{
cout << name << " " << age << endl;
}
};
void Dogfriend(Dog &d)
{
cout << d.name << endl;
cout << d.age << endl;
}
int main()
{
Dog("白",9);//匿名对象
Dog d1 = Dog("黑",6);//给有名对象初始化
Dogfriend(d1);//作为函数的参数
return 0;
}
5.总结
匿名对象相较于有名对象,简化了对于对象名的定义,在函数传参时,可以不用先初始化,在进行对象名传参,更加快捷方便
二.友元
1.作用
让一些函数或者类,去访问另一个类的私有属性
2.种类
1.全局函数作为友元
2.类作为友元
3.成员函数作为友元
3.全局函数作为友元
定义一个函数进行访问类中的私有属性,照常来说是不能访问的,在类的最前面加上friend,就是给函数作为友元,则可以访问私有属性
#include <iostream>
using namespace std;
class Dog
{
friend void Dogfriend(Dog &b);//全局函数作为友元
private:
string name;
int age;
public:
Dog()
{
}
Dog(string name,int age):name(name),age(age)
{
cout << name << " " << age << endl;
}
};
void Dogfriend(Dog &d)
{
cout << d.name << endl;
cout << d.age << endl;
}
int main()
{
Dog("白",9);
Dog d1 = Dog("黑",6);
Dogfriend(d1);
return 0;
}
4.类作为友元
#include <iostream>
using namespace std;
class Dog
{
friend class Dogfriend;
private:
string name;
int age;
public:
Dog()
{
}
Dog(string name,int age):name(name),age(age)
{
cout << name << " " << age << endl;
}
};
class Dogfriend
{
private:
Dog *d;
public:
Dogfriend(string name,int age)
{
d = new Dog(name,age);
}
void visit()
{
cout << d->age << endl;
cout << d->name << endl;
}
};
int main()
{
Dog("白",9);
Dogfriend d1("黑",6);
d1.visit();
return 0;
}
5.成员函数作为友元
在定义访问类时,需要注意访问类的成员函数作为友元,这个友元必须得在访问类完全定义后才能作为友元,所以需要将Dogfriend移到Dog前面,但是由于Dogfriend有使用Dog的成员,所以需要类外定义成员函数
#include <iostream>
using namespace std;
class Dog;
class Dogfriend
{
private:
Dog *d;
public:
Dogfriend(string name,int age);
void visit();
};
class Dog
{
friend void Dogfriend::visit();
private:
string name;
int age;
public:
Dog()
{
}
Dog(string name,int age):name(name),age(age)
{
cout << name << " " << age << endl;
}
};
Dogfriend::Dogfriend(string name,int age)
{
d = new Dog(name,age);
}
void Dogfriend::visit()
{
cout << d->age << endl;
cout << d->name << endl;
}
int main()
{
Dog("白",9);
Dogfriend d1("黑",6);
d1.visit();
return 0;
}
6.总结
1.友元容易破坏类的封装性,请谨慎使用
2.友元不具有交互性、传递性、继承性
三.常成员函数与常对象
1.常成员函数
a.作用
将成员函数定义为常成员函数后,函数不能修改成员的值
b.格式
class 类名
{
返回值类型 函数名(形参列表) const // 常成员函数
{
函数体内容;
}
};
c.例子
#include <iostream>
using namespace std;
class Dog
{
private:
string name;
int age;
public:
Dog()
{
}
Dog(string name,int age):name(name),age(age)
{
}
void show()//非常成员函数
{
age = 3;
cout << age <<endl;
cout << name << endl;
}
void show() const//常成员函数
{
cout << age <<endl;
cout << name << endl;
}
};
int main()
{
Dog("白",9);
Dog d1 = Dog("黑",6);
Dog const d2 = Dog("黄",4);
d1.show();
d2.show();
return 0;
}
2.常对象
a.作用
让该对象的数据成员不能被改变
b.格式
const 类名 对象名
c.注意事项
1.常对象只能调用常成员函数,不能调用非常成员函数
2.非常对象二者都能调用,非常对象默认调用非常成员函数
d.例子
#include <iostream>
using namespace std;
class Dog
{
private:
string name;
int age;
public:
Dog()
{
}
Dog(string name,int age):name(name),age(age)
{
}
void show()
{
age = 3;
cout << age <<endl;
cout << name << endl;
}
void show() const
{
cout << age <<endl;
cout << name << endl;
}
};
int main()
{
Dog("白",9);
Dog d1 = Dog("黑",6);
Dog const d2 = Dog("黄",4);//常对象
d1.show();
d2.show();
return 0;
}
3.mutable关键字
a.作用
让数据成员可以在常成员函数中修改
b.例子
#include <iostream>
using namespace std;
class Dog
{
private:
string name;
mutable int age;
public:
Dog()
{
}
Dog(string name,int age):name(name),age(age)
{
}
void show()
{
age = 3;
cout << age <<endl;
cout << name << endl;
}
void show() const
{
age = 3;//常成员函数中修改
cout << age <<endl;
cout << name << endl;
}
};
int main()
{
Dog("白",9);
Dog d1 = Dog("黑",6);
Dog const d2 = Dog("黄",4);//常对象
d1.show();
d2.show();
return 0;
}
c.总结
mutable破坏了常成员函数的目的:不改变成员的值。尽量不使用
四.运算符重载
1.定义
对运算符进行重新定义,让其可以适应不同的数据类型
2.使用场景
普通的运算符只能运算基本数据类型,构造数据类型无法运算,运算符重载让重新定义的运算符可以运算构造数据类型
3.实现方式
1.成员函数用作运算符重载
2.全局函数用作运算符重载
4.函数格式
1.成员函数用作运算符重载:
const 类名 operator#(const 类名 &R) const
num n3 = n1+n2; -->num n3 = n1.operator+(n2);
2.全局函数用作运算符重载
const 类名 operator#(const 类名 &L, const 类名 &R)
num n3 = n1+n2; -->num n3 = operator+(n1,n2);
4.例子
#include <iostream>
using namespace std;
class num
{
// friend const num operator+(const num &L,const num &R);
private:
int a;
int b;
public:
num(){}
num(int a,int b):a(a),b(b){}
//成员函数用作运算符重载
const num operator+(const num &R) const
{
num temp;
temp.a = a + R.a;
temp.b = b + R.b;
return temp;
}
const num operator-(const num &R) const
{
num temp;
temp.a = a - R.a;
temp.b = b - R.b;
return temp;
}
const num operator*(const num &R) const
{
num temp;
temp.a = a * R.a;
temp.b = b * R.b;
return temp;
}
const num operator/(const num &R) const
{
num temp;
temp.a = a / R.a;
temp.b = b / R.b;
return temp;
}
void show()
{
cout << "a = " << a << " b = " << b << endl;
}
};
//全局函数用作运算符重载
//const num operator+(const num &L,const num &R)
//{
// num temp;
// temp.a = L.a + R.a;
// temp.b = L.b + R.b;
// return temp;
//}
int main()
{
num n1(2,3);
num n2(3,4);
num n3 = n1+n2;
num n4 = n1-n2;
num n5 = n1*n2;
num n6 = n1/n2;
n3.show();
n4.show();
n5.show();
n6.show();
return 0;
}