2020.11.12 第4节 特殊成员
一、const成员
const 成员
const:不能修改 常属性
1.const 数据成员
1.1 只能采用初始化参数列表的方式进行初始化
构造函数名(参数1,参数2,...):数据成员1(参数1),数据成员2(参数2)...{}
1.2 构造函数必须要初始化常数据成员
在学常量的时候,常量必须初始化 常量的基本规则
2.const 成员函数
2.1 注意写法
const放在函数后面
2.2 注意限定
不能修改数据
2.3 常成员函数可以和普通函数共存
3.const 对象
常对象只能调用常成员函数
普通对象优先调用普通函数
#include <iostream>
#include <string>
using namespace std;
class MM
{
public:
MM(string name):num(0)
{
this->name = name;
}
MM(string name, int age) :name(name), age(age), num(0)
{
}
MM(string name, int age, int num) :num(num)
{
this->name = name;
this->age = age;
}
void print()
{
cout << name<<":" << age << endl;
}
void print() const
{
int i =0 ; i++;
cout << "常函数" << endl;
cout << name << ":" << age <<":"<<num<< endl;
}
protected:
string name;
int age;
const int num;
};
class boy
{
public:
boy(const char* str) :str(str)
{
}
boy() :str("Iloveyou")
{
}
const char* str;
};
int main()
{
const MM mm("Love");
mm.print();
MM myMM("小仙女", 18);
myMM.print();
return 0;
}
二、静态成员
static 修饰 静态成员属于类 ,不属于对象 调用不需要对象
1.static数据成员
1.1 注意初始化
1.1.1 类外初始化 但还是本类 重点
NO.1 需要前缀
NO.2 依旧受权限限定词限定
1.2 注意调用
1.2.1 它的使用可以不需要对象
1.2.2 依旧受权限和类名限定词限定
2.static成员函数
2.1 static 修饰的函数 可以访问保护属性 普通函数不行
类内 类外 都可实现 类外需要类的限定 不需要static
2.2 调用与访问问题
2.2.1 调用也不需要对象
2.2.1 依旧受权限和类名限定词限定
#include <iostream>
#include <string>
using namespace std;
class MM
{
public:
MM(string name) :name(name)
{
count++;
}
void print()
{
cout << count << endl;
}
static void printInfo();
static void printData(MM oject);
protected:
string name;
public:
static int count;
};
int MM::count = 0;
void MM::printInfo()
{
cout << count << endl;
}
void MM::printData(MM object)
{
cout << object.name << endl;
cout << count << endl;
}
int main()
{
cout << MM::count << endl;
MM mm1("yykk");
MM mm2("oracle");
MM mm3("LBW");
cout << MM::count << endl;
mm1.print();
MM::printInfo();
MM::printData(mm3);
return 0;
}
三、友元函数
1.友元函数:friend关键字修饰的函数就是友元函数
1.1 类外实现不需要friend修饰
1.2 有元函数不属于类,类外实现不需要加类名限定
1.3 在当前函数中赋予对象具有打破类的权限限定 !! 对象
no.1传参的对象/对象指针
no.2在函数体创建对象
打破类的封装和隐藏性
以另一个类的成员成员函数为友元函数 了解
2.友元类
#include <iostream>
#include <string>
using namespace std;
class MM
{
friend void makeBoyFriend();
friend void makeBoyFriend(MM object);
public:
MM(string name, int age, int money) :name(name), age(age), money(money) {};
string name;
protected:
void print()
{
cout << name << ":" << age << ":" << money << endl;
}
int age;
private:
int money;
};
void makeBoyFriend()
{
MM boy("yykk", 18, 100);
boy.print();
cout << boy.name << ":<<" << boy.age << ":" << boy.age << endl;
}
void makeBoyFriend(MM object)
{
object.print();
}
class Girl;
class Boy
{
public:
void makeGirlFriend(Girl girl)
{
cout << girl.name << ":" << girl.age << endl;
}
protected:
};
class Girl
{
friend void Boy::makeGirlFriend(Girl girl);
public:
Girl(string name, int gae) :name(name), age(age) {}
string name;
protected:
int age;
};
void Boy::makeGirlFriend(Girl girl)
{
cout << girl.name << ":" << girl.age << endl;
}
int main()
{
MM mm("yykk", 18, 100);
makeBoyFriend(mm);
Girl girl("Oracle", 19);
Boy boy;
boy.makeGirlFriend(girl);
return 0;
}
四、友元类
友元类:
把另一个当作一个类的友元 ,另一个类的对象就可以随意访问
互为友元类:
注意写法 声明问题
#include <iostream>
#include <string>
using namespace std;
class Girl
{
friend class Boy;
public:
Girl(string name,int age):name(name),age(age){}
void print()
{
}
string name;
protected:
int age;
};
class Boy
{
public:
void print()
{
Girl girl("Oracle", 18);
cout << girl.name << ":" << girl.age << endl;
}
void print(Girl object)
{
cout << object.name << ":" << object.age << endl;
}
protected:
};
class A
{
friend class B;
public:
A(int a):a(a){}
void print(B object);
protected:
int a;
};
class B
{
friend class A;
public:
B(int b) :b(b) {}
void print()
{
A object(1);
cout << object.a << endl;
}
protected:
int b;
};
void A::print(B object)
{
cout << object.b << endl;
}
int main()
{
Boy boy;
boy.print();
A a(1);
B b(2);
a.print(b);
b.print();
return 0;
}
五、类的组合
类的组合:
以另一个类的对象为数据成员
1.构造函数写法
1.1 必须初始化参数列表方式调用组合类的构造函数
1.2 组合类必定会调用其他类的构造函数
(
2. 构造和析构顺序问题
#include <iostream>
using namespace std;
class Clothes
{
public:
Clothes(int color=0):color(color)
{
cout << "A" << endl;
}
protected:
int color;
};
class Cosmetics
{
public:
Cosmetics(int money=0):money(money)
{
cout << "B" << endl;
}
protected:
int money;
};
class MM
{
public:
MM(string name,int color,int money):cloth(color),cosmetic(money)
{
this->name = name;
cout << "C1" << endl;
}
MM(string name):name(name)
{
cout << "C2" << endl;
}
protected:
string name;
Clothes cloth;
Cosmetics cosmetic;
};
int main()
{
MM mm("LBW",1,100);
return 0;
}
六、类中成员函数指针
类的成员函数的函数指针
区别:声明的时候
1.类的限定
2.成员函数取地址
#include <iostream>
using namespace std;
class MM
{
public:
MM(string name,int age):name(name),age(age){}
void print()
{
cout << name << "\t" << age << endl;
}
protected:
string name;
int age;
};
int main()
{
MM mm("Bug", 10);
void (MM:: * p)() = &MM::print;
(mm.*p)();
return 0;
}#include <iostream>
using namespace std;
class MM
{
public:
MM(string name, int age) :name(name), age(age) {}
void print()
{
cout << name << "\t" << age << endl;
}
protected:
string name;
int age;
};
int main()
{
MM mm("Bug", 10);
void (MM:: * p)() = &MM::print;
(mm.*p)();
return 0;
}