友元的概念
友元是赋予全局函数,类的成员函数,类,访问别的类的私有成员权限
注意:友元函数不是类的成员函数
1.全局友元函数
#include <iostream>
using namespace std;
#include <string>
#include <cstring>
class Man
{
friend void Goodgay(Man &mm);
public:
Man(int id,int age)
{
this->id=id;
this->age=age;
}
private:
int id;
int age;
};
void Goodgay(Man &mm)
{
cout<<mm.id<<endl;
cout<<mm.age<<endl;
}
int main()
{
Man m(1,30);
Goodgay(m);
return 0;
}
[Running] cd "d:\cppproject\" && g++ test01.cpp -o test01 && "d:\cppproject\"test01
1
30
2.友元类
#include <iostream>
using namespace std;
#include <string>
#include <cstring>
class Man
{
friend class Goodgay;//声明Goodgay类为Building类的友元类
public:
Man(int id,int age)
{
this->id=id;
this->age=age;
}
private:
int id;
int age;
};
class Goodgay
{
public:
void func(Man &m)
{
cout<<m.id<<endl; //通过参数访问私有成员
cout<<m.age<<endl;
}
};
int main()
{
Man m(2,44);
Goodgay g;
g.func(m); //1.通过传入参数来访问类的私有成员
return 0;
}
[Running] cd "d:\cppproject\" && g++ test01.cpp -o test01 && "d:\cppproject\"test01
2
44
#include <iostream>
using namespace std;
#include <string>
#include <cstring>
class Man
{
friend class Goodboy;
public:
Man(int id,int age)
{
this->id=id;
this->age=age;
}
private:
int id;
int age;
};
//通过类内指针来访问类的私有成员
class Goodboy
{
public:
Goodboy()
{
ptu=new Man(2,66);
}
void func()
{
cout<<ptu->id<<endl;
cout<<ptu->age<<endl;
}
~Goodboy()
{
if(ptu!=NULL)
{
delete ptu;
}
}
Man *ptu;
};
int main()
{
Goodboy gb;
gb.func();
return 0;
}
[Running] cd "d:\cppproject\" && g++ test01.cpp -o test01 && "d:\cppproject\"test01
2
66
3.类的友元成员函数(难点)
//1.编译器知道类的声明,不知道类的结构
class Building;//声明类
class GoodGay
{
public:
void func(Building &bud);
};
class Building
{
//声明GoodGay类的成员函数func成为Building类的友元函数
friend void GoodGay::func(Building &bud);
public:
Building()
{
keting = "客厅";
woshi = "卧室";
}
public:
string keting;
private:
string woshi;
};
void GoodGay::func(Building &bud)
{
cout << "访问:" << bud.keting << endl;
cout << "访问:" << bud.woshi << endl;
}
void test()
{
Building bud;
GoodGay GF;
GF.func(bud);
}
4.友元的注意:
1.友元关系不能被继承。
2.友元关系是单向的,类A是类B的朋友,但类B不一定是类A的朋友。
3.友元关系不具有传递性。类B是类A的朋友,类C是类B的朋友,但类C不一定是类A的朋友。
单例模式(重点难点)
1.单例模式是一个类只能实例化一个对象
2.实现单例模式的思路
1.把无参构造函数和拷贝构造函数私有化
2.定义一个类内的静态成员指针
3.在类外初始化时,new一个对象
4.把指针的权限设置为私有,然后提供一个静态成员函数让外面获取这个指针
//单例模式是一个类只能实例化一个对象
class Maker
{
//1.把构造函数私有化
private:
Maker()
{
}
Maker(const Maker &m)
{
}
public:
//静态成员函数,访问静态成员变量
//4.把指针的权限设置为私有,然后提供一个静态成员函数让外面获取这个指针
static Maker* getMaker()
{
return pMaker;
}
private:
//2.定义一个类内的静态成员指针
static Maker *pMaker;
};
//3.在类外初始化时,new一个对象
Maker *Maker::pMaker = new Maker;//这里可以new是因为在Maker::作用域,编译器把它当成在类内
void test()
{
//Maker m;
Maker *m = Maker::getMaker();
Maker *m2 = Maker::getMaker();
cout << "m=" << m << endl;
cout << "m2=" << m2 << endl;
//Maker m3 = *m;//调用拷贝构造,这里会产生新对象,所以要把拷贝构造也私有化
//cout << "m3=" << &m3 << endl;
}
//3.单例模式案例(需求:获取打印机打印次数)
//需求,获取打印机使用的次数
class Printer
{
private:
//1.把无参构造和拷贝构造私有化
Printer()
{
mcount = 0;
}
Printer(const Printer &p)
{
}
public:
static Printer *getPrinter()
{
return p;
}
void printPrinter(string name)
{
cout << name << ":打印" << endl;
mcount++;
}
int getCount()
{
return mcount;
}
private:
int mcount;//记录打印打印的次数
//2.定义静态成员指针
static Printer *p;
};
//3.类外进行初始化,new对象
Printer *Printer::p = new Printer;
void test()
{
//销售部
Printer *p1 = Printer::getPrinter();
p1->printPrinter("销售部");
//技术部
Printer *p2 = Printer::getPrinter();
p2->printPrinter("技术部");
//公关部
Printer *p3 = Printer::getPrinter();
p3->printPrinter("公关部");
Printer *p4 = Printer::getPrinter();
cout << "打印使用的次数:"<<p4->getCount() << endl;
}
练习:
#include <iostream>
using namespace std;
#include <string>
#include <cstring>
class Man
{
//1.把构造函数私有化
private:
Man()
{
}
Man(const Man &m)
{
}
public:
static Man* getMan()
{
return pMan;
}
private:
static Man *pMan;
};
Man * Man::pMan = new Man;
int main()
{
Man * m1= Man::getMan();
Man * m2= Man::getMan();
cout << "m1=" << m1 << endl;
cout << "m2=" << m2 << endl;
//Man m3 = *m;//调用拷贝构造,这里会产生新对象,所以要把拷贝构造也私有化
//cout << "m3=" << &m3 << endl;
return 0;
}
[Running] cd "d:\cppproject\" && g++ test01.cpp -o test01 && "d:\cppproject\"test01
m1=0x2b6fd6c1820
m2=0x2b6fd6c1820
#include <iostream>
using namespace std;
#include <string>
#include <cstring>
class Printer
{
//1.把构造函数私有化
private:
Printer()
{
count=0;
}
Printer(const Printer &m)
{
}
public:
static Printer* getPrinter()
{
return pPrinter;
}
void PrintPrinter(string name )
{
cout<<name<<":打印"<<endl;
count++;
}
int getPrintCount()
{
return count;
}
private:
int count;
static Printer *pPrinter;
};
Printer * Printer::pPrinter = new Printer;
int main()
{
Printer * m1= Printer::getPrinter();
m1->PrintPrinter("技术部");
Printer * m2= Printer::getPrinter();
m1->PrintPrinter("业务部");
Printer * m3= Printer::getPrinter();
cout<<"打印次数:"<<m3->getPrintCount()<<endl;
return 0;
}
[Running] cd "d:\cppproject\" && g++ test01.cpp -o test01 && "d:\cppproject\"test01
技术部:打印
业务部:打印
打印次数:2