記錄C++的學習2
阿新 • • 發佈:2021-01-13
技術標籤:C++學習
記錄c++的學習2
(僅供參考,歡迎大家交流學習)
2021.1.10
4、友元:
4.1全域性函式做友元:
1、友元的目的就是讓一個函式或者類訪問另一個類中私有成員
2、友元的關鍵字為friend
3、友元的三種實現
(1)全域性函式做友元
(2)類做友元
(3)成員函式做友元
4、友元是C++提供的一種破壞資料封裝和資料隱藏的機制。
5、若一個類為另一個類的友元,則此類的所有成員函式都能訪問對方類的私有成員。
6、單向性:如果宣告B類是A類的友元, B類的成員函式就可以訪問A類的私有和保護資料,但A類的成員函式卻不能訪問B類的私有、保護資料。不可傳遞性,不可繼承性:。
下面展示一些 程式碼
。
#include <iostream>
#include <string>
using namespace std;
class Person
{
//友元函式宣告:
friend void test01(Person *p);
public:
Person()
{
home="我家";
phone="我手機";
}
string home;
private:
string phone;
};
//全域性函式:
void test01(Person *p)//用指標或者是用引用都可以
{//不過用指標就必須是p->home,引用是p.home
cout<<"好朋友來"<<p->home<<endl;
cout<<"好朋友可以看"<<p->phone<<endl;
}
void test02()
{
Person p;
test01(&p);//傳入指標,所以用&p
}
int main()
{
test02();
system("pause");
return 0;
}
4.2 類做友元:
下面展示一些 程式碼
。
#include <iostream>
#include <string>
using namespace std;
//類做友元:
//若一個類為另一個類的友元,則此類的所有成員函式都能訪問對方類的私有成員。
class A
{
friend class B;//賦予B類友元的許可權
public:
void Display()//設定一個函式輸出x的值
{
cout<<x<<endl;
}
private:
int x;
};
class B
{
public:
void Set(int i)
{
a.x=i;
/*因為A類賦予了B類友元關係,故在B類中可以直接訪問
A類物件a的私有資料成員*/
}
void Display()
{
a.Display();
}
private:
A a;
};
void test01()
{
B a;
a.Set(3);
a.Display();
}
int main()
{
test01();
system("pause");
return 0;
}
4.3 成員函式做友元:
5、運算子過載:
5.1 加號運算子過載:
#include <iostream>
using namespace std;
//加號運算子過載
//1、成員函式過載+號
class Person
{
public:
/*Person operator+(Person &p)
{
Person temp;
temp.a=this->a+p.a;
temp.b=this->b+p.b;
return temp;
}*/
int a;
int b;
};
//void test01()
//{
// Person p1;
// p1.a=10;
// p1.b=10;
// Person p2;
// p2.a=10;
// p2.b=10;
// Person p3;
// p3=p1+p2;
// cout<<"P3.a="<<p3.a<<endl;
// cout<<"P3.b="<<p3.b<<endl;
//}
//2、全域性函式過載+號
Person operator+(Person &p3,Person &p4)
{
Person temp1;
temp1.a=p3.a+p4.a;
temp1.b=p3.b+p4.b;
return temp1;
}
Person operator+(Person &p3,int num)
{
Person temp1;
temp1.a=p3.a+num;
temp1.b=p3.b+num;
return temp1;
}
void test02()
{
Person p3;
p3.a=15;
p3.b=15;
Person p4;
p4.a=15;
p4.b=15;
Person p5;
p5=p3+p4;
cout<<"P5.a="<<p5.a<<endl;
cout<<"P5.b="<<p5.b<<endl;
Person p6;
p6=p3+100;
cout<<"P6.a="<<p6.a<<endl;
cout<<"P6.b="<<p6.b<<endl;
}
//成員函式過載本質呼叫:
//Person p3=p1.operator+(p2);
//全域性函式過載本質呼叫
//Person p3=operator+(p1,p2);
//運算子過載,也可以發生函式過載
int main()
{
test02();
system("pause");
return 0;
}
5.2 左移運算子過載:
#include <iostream>
using namespace std;
class Person
{
friend ostream & operator<<(ostream &cout,Person &p);//運用友元函式訪問private
public:
Person (int a,int b)
{
this->a=a;
this->b=b;
}
private:
int a;
int b;
};
/*利用成員函式過載 左移運算子 p.operator<<(cout) 簡化為p<<cout。
不會利用成員函式過載<<運算子,因為無法實現cout在左側*/
//只能利用全域性函式過載左移運算子:
ostream & operator<<(ostream &cout,Person &p)//本質 operator<<(cout,p),簡化為cout<<p
//輸出流物件,全域性只能有一個,用引用的方式傳遞。
{
cout <<"a="<<p.a<<endl;
cout <<"b="<<p.b<<endl;
return cout;
}
void test01()
{
Person p(1024,1024);
cout<<p;
}
int main()
{
test01();
system("pause");
return 0;
}
5.3 遞增運算子過載:
#include <iostream>
using namespace std;
//過載遞增運算子
//自定義整型
class MyInteger
{
friend ostream & operator<<(ostream& cout,MyInteger &myint);
public:
MyInteger()
{
num=0;
}
//過載前置++運算子
MyInteger& operator++()
//必須用引用&,目的是一直對一個數據進行操作
{
//先進行++運算
num++;
//再將自身做一個返回
return *this;//*this,將自身作為返回
}
//過載後置++運算子
//int代表佔位引數,可以用於區分前置和後置遞增
MyInteger operator++(int)//後置返回值,前置返回引用
{
//先記錄當時結果
MyInteger temp=*this;
//後遞增
num++;
//最後將記錄結果做一個返回操作
return temp;
}
private:
int num;
};
void test01()
{
MyInteger myint;
cout<<++myint<<endl;
cout<<myint<<endl;
}
void test02()
{
MyInteger myint;
cout<<myint++<<endl;
cout<<myint<<endl;
}
ostream & operator<<(ostream& cout,MyInteger &myint)
{
cout<<myint.num;
return cout;
}
int main()
{
cout<<"前置++運算子:"<<endl;
test01();
cout<<"後置++運算子:"<<endl;
test02();
system("pause");
return 0;
}
5.4 賦值運算子過載:
1、賦值運算子operator=,對屬性進行拷貝,如果有屬性指向堆區,做賦值操作時,也會出現深淺拷貝的問題。
#include <iostream>
using namespace std;
//賦值運算子過載
class Person
{
public:
Person(int age1)
{
age=new int(age1);
}
~Person()
{
//堆區記憶體重複釋放,會導致程式崩潰。
if(age!=NULL)
{
delete age;
age=NULL;
}
}
//過載 賦值運算子
Person& operator=(Person &p)
{
//編譯器提供淺拷貝age=p.age;
//應該先判斷是否有屬性在堆區,如果有,先釋放乾淨,然後再深拷貝。
if(age!=NULL)
{
delete age;
age=NULL;
}
age=new int (*p.age);//深拷貝
//返回物件本身
return *this;
}
int *age;
};
void test01()
{
Person p1(18);
Person p2(20);
Person p3(25);
p3=p2=p1;
p2=p1;//賦值操作
cout<<"p1的年齡為:"<<*p1.age<<endl;
cout<<"p2的年齡為:"<<*p2.age<<endl;
cout<<"p3的年齡為:"<<*p3.age<<endl;
}
int main()
{
test01();
system("pause");
return 0;
}