0902 C++类的匿名对象
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;
}