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;
}