一 友元
- 类似 java 中享元模式:实例的共享(ImageLoader Lru 算法 存储图片)
- 友元:类或函数的共享
- 优点:提高效率、表达清晰
- 缺点:破坏封装性
- 特征:
友元函数不能被派生类继承
友元函数不能使用this
1 友元函数
#include <string>
#include <iostream>
using namespace std;
class Girl
{
public :
friend void modify(Girl *girl ,int age);
void tell();
private:
int age = 16;
};
//Girl class的函数实现
void Girl::tell(){
cout << "age == " << age << endl;
}
//没有限定符,外部实现
void modify(Girl *girl, int age) {
girl->age = age;
}
void main() {
Girl *girl = new Girl();
girl->tell();
modify(girl, 31);
girl->tell();
delete girl;
system("pause");
}
运行结果:
age == 16
age == 31
2 友元类
让其他类中的成员函数访问这个类中的私有函数
Class A 有属性 a,Class B可以访问 Class C不可以访问
#include <string>
#include <iostream>
using namespace std;
class Girl
{
public :
friend class Boy;
void tell();
private:
int age = 16;
string name= "tt";
};
//Girl class的函数实现
void Girl::tell(){
cout << "age == " << age << endl;
}
class Boy
{
public:
Boy(Girl girl) {
this->girl = girl;
}
~Boy() {
}
void changeGril() {
girl.age = 20;
girl.name = "xx";
}
//已经声明为友元类,可以访问和修改私有属性
void introuduce() {
cout << "My Gril friend name:" <<girl.name<<" age:"<< girl.age << endl;
}
private:
Girl girl;
};
void main() {
Girl girl;
Boy boy = Boy(girl);
boy.introuduce();
boy.changeGril();
boy.introuduce();
system("pause");
}
运行结果:
My Gril friend name:tt age:16
My Gril friend name:xx age:20
拓展: 实现类中的友元函数,friend void Boy::introduce();
二 模板函数
跟java中的泛型类型
- 有一个int值交换需求
void myswap(int& a, int& b) {
int temp = 0;
temp = a;
a = b;
b = temp;
}
void main() {
int a = 999;
int b = 666;
myswap(a, b);
cout << "a = " << a << " b = " << b << endl;
system("puase");
}
运行结果:a = 666 b = 999
- 由int类型改成交换char 类型
void myswap(char& a, char& b) {
char temp = 0;
temp = a;
a = b;
b = temp;
}
void main() {
char a = 'a';
char b = 'h';
myswap(a, b);
cout << "a = " << a << " b = " << b << endl;
system("pause");
}
结果:a = h b = a
3. c中可以利用模板函数实现
template <typename T>
void myswap(T& a, T& b) {
T temp = 0;
temp = a;
a = b;
b = temp;
}
void main() {
int a = 999;
int b = 666;
myswap(a, b);
cout << "a = " << a << " b = " << b << endl;
char c = 'a';
char d = 'h';
myswap(c, d);
cout << "c = " << c << " d = " << d << endl;
system("pause");
}
运行结果:
a = 666 b = 999
c = h d = a
三 模板类
template <class T>
class A
{
public:
A(T a) {
this->a = a;
}
~A() {
}
protected:
T a;
};
template<class T>
class C :public A<T>
{
public:
C(T c,T a):A<T>(a) {
this->c = c;
}
void tell() {
cout << "a:" << a << " c:" << c << endl;
}
private:
T c;
};
四 类型转换
1 可以直接强制类型转换
int i = 8;
double d = 9.5;
i = (int)d;
原始类型转换,所有情况都是一种写法;可读性性不高,没有提示,有转换风险
2 static_cast普通值类型转换
i = static_cast<int>(d);
3 const_cast 去常量
void func(const char c[]) {
//c[1] = a;
//去掉const 关键字
char* c_p = const_cast<char *>(c);
c_p[1] = 'X';
}
void main() {
i = static_cast<int>(d);
char c[] = "hello";
cout << "c = " << c << endl;
func(c);
cout << "c = " << c << endl;
system("pause");
}
运行结果:
c = hello
c = hXllo
4 dynamic_cast基类和派生类之间的转换
class Person {
public :
virtual void print() {
cout << "Person" << endl;
}
};
class Man :public Person {
public:
void print() {
cout << "Man" << endl;
}
void chasing() {
cout << "chasing" << endl;
}
};
class Woman :public Person {
public:
void print() {
cout << "Man" << endl;
}
void createBaby() {
cout << "createBaby" << endl;
}
};
void funx(Person * obj) {
//Man *m = (Man *)obj;//如果是Woman会有问题
//m->chasing();
Man *m = dynamic_cast<Man*>(obj);
if (m != nullptr) {
m->chasing();
}
else {
cout << " 不是Man的类型" << endl;
}
}
void main() {
Woman *wm = new Woman();
funx(wm);
system("pause");
}
运行结果:不是Man的类型
5 reinterpret_cat 函数指针的转换
((Void*)p)
不常用的方法,一般在Void *之间
五 异常
void main() {
try {
int age = 300;
if (age > 200) {
throw 9;
}
}
catch (int a) {
cout << "int 异常" << a<< endl;
}
system("pause");
}
结果:int 异常9
多种类型的(char * 先在 vs项目属性中设置符合模式)
void main() {
try {
int age = 300;
if (age > 200) {
throw "xxx";
}
}
catch (int a) {
cout << "int 异常" << a<< endl;
}
catch (char * b) {
cout << "char *b" << b << endl;
}
system("pause");
}
结果:char *bxxx
标准异常
类似于java中javaNullPointerException
class NullPointerException :public exception {
public :
NullPointerException(char * msg) :exception(msg){
}
};
void main() {
try {
int age = 300;
if (age > 200) {
throw NullPointerException("pgone");
}
}
catch (int a) {
cout << "int 异常" << a << endl;
}
catch (char * b) {
cout << "char *b" << b << endl;
}
catch (NullPointerException e) {
cout << "NullPointerException: " <<e.what() << endl;
}
system("pause");
}
结果:NullPointerException: pgone