封装
-
意义
-
将属性和行为作为一个整体,表现事物
-
将属性和行为加以权限控制
class 类名{ 访问权限: 属性/行为};
-
-
访问权限
- public 成员在类内可以,类外可以访问
- protected 成员在类内可以访问,类外不可以访问,儿子可以访问父亲中的保护内容
- private 成员在类内可以访问,类外不可以访问,儿子不可以访问父亲的私有内容
-
struct 和 class的区别
- 唯一的区别是默认权限不一样
- struct 默认公共权限, class 默认私有
-
成员属性私有化
- 可以自己控制读写权限
- 对于写权限,可以检测数据的有效性
对象的初始化和清理
-
构造函数
- 构造对象是为对象的成员赋值
类名(){}
- 可以重载
- 自动调用一次
-
析构函数
-
对象销毁前的系统自动调用
-
~类名(){}
-
class Person
{
private:
int age;
public:
Person()//无参构造、普通构造
{
cout <<"构造函数的调用"<<endl;
}
Person(int a)//有参构造、普通构造
{
age = a;
cout <<"有参构造的调用"<<endl;
}
Person(const Person &p) //拷贝构造
{
//将传入对象的属性拷贝到自身
age = p.age
cout << "拷贝构造的调用" <<endl;
}
~Person()//不可以有参数,不可以发生重载
{
cout <<"析构函数的调用"
}
}
void func1()
{
Person p;
}
int main()
{
func1(); //既调用构造函数,也调用析构函数;
//因为对象建立在栈中,调用结束即回收释放内存
//1.括号法
Person p; //只调用构造函数,默认构造
Person P(10);//调用有参构造函数
Person P2(P);//调用拷贝构造函数
//调用默认构造函数的时候,不加括号,若加了括号,编译器会认为是函数声明
//Person p() 不创建任何对象
//2.显式构造
Person p1;
Person p2 = Person(10);// 有参构造
Person p3 = Person(p2);//拷贝构造
Person(10); //匿名对象,执行结束后,立马回收掉匿名对象
//注意 不要用拷贝构造函数,初始化匿名对象
//Person(p3) == Person p3;
//3、隐式转换法
Person p4 = 10; //有参构造
Person p5 = p4; //拷贝构造
return 0;
}
this 指针
this 指向调用成员函数的对象
class Person
{
public:
Person(int age)
{
this->age = age;
}
Person& PersonAddAge(Person &p) // 用引用来保存指针避免拷贝
{
this->age += p.age;
return *this//返回指向对象的指针
}
test01()
{
Person p1(10);
Person p2(10);
p2.PersonAddAge(10).PersonAddAge(10).PersonAddAge(10);
//链式编程,p2.age = 40
}
}
空指针调用成员函数
void func()
{
if (this == NULL)
{
return;//空指针直接返回,避免程序崩溃
}
cout <<"age = " << this->age <<endl;
}
Const 修饰成员函数
成员函数后加const 即为常函数
对象前加const为常对象,
常对象只能调用常函数
class Person
{
public:
int m_a;
mutable int m_b;//特殊变量,在常函数中也可以修改
//this是指针常量,指向不可修改
Person* const this;
void showPerson() const//指针所指向的值不可以修改
{
this->m_A = 100; //不允许,因为指针指向的对象不可修改
this->m_b = 100;//允许,mutable定义的特殊变量可修改
this = NULL; //this指针不允许修改
}
}
友元
有些私有属性,可以让类外一些函数或者类进行访问
-
全局函数做友元
class Building { //给goodGay权限访问私有变量 friend void goodGay(Building *building); public: Building() { m_SittingRoom = "客厅"; m_BedRoom = "卧室"; } string m_SittingRoom; private: string m_BedRoom; } void GoodGay(Building *building)//可以访问私有变量 { cout << "访问" << building-> m_BedRoom << endl; }
-
类做友元
class GoodGay { public: GoodGay(); void visit(); Building* building; }; class Building { friend class GoodGay;// 类做友元 public: Building(); string m_SittingRoom; private: string m_BedRoom; }; Building::Building() { m_SittingRoom = "sittingRoom"; m_BedRoom = "BedRoom"; } GoodGay::GoodGay() { building = new Building; } void GoodGay::visit() { cout << "access the public member:" << building->m_SittingRoom << endl; cout << "access the private menber:" << building->m_BedRoom << endl; } int main() { GoodGay g; g.visit(); return 0; }
-
成员函数做友元
class Building; class GoodGay { public: GoodGay(); void visit();// visit can access the private menber in building void visit2();//visit2 can't access the private menber in building Building* building; }; class Building { public: friend void GoodGay::visit(); //成员函数做友元 Building(); string m_SittingRoom; private: string m_BedRoom; }; Building::Building() { m_SittingRoom = "sittingRoom"; m_BedRoom = "BedRoom"; } GoodGay::GoodGay() { building = new Building; } void GoodGay::visit() { cout << "access the public member:\t" << building->m_SittingRoom << endl; cout << "access the private menber:\t" << building->m_BedRoom << endl; } void GoodGay::visit2() { cout << "access the public member:\t" << building->m_SittingRoom << endl; } int main() { GoodGay g; g.visit(); g.visit2(); return 0; }
运算符重载
class Person
{
public:
int m_A;
int m_B;
Person(int a, int b)
{
m_A = a;
m_B = b;
cout << "call struct" << endl;
}
//Person operator+ (Person& p)//成员函数重载加号运算符
//{
// Person p2(this->m_A + p.m_A, this->m_B + p.m_B);
// return p2;
//}
};
Person operator+(Person& A, Person& B)
{
Person C(A.m_A + B.m_A, A.m_B + B.m_B);
return C;
}
int main()
{
int age = 10;
int age2 = 20;
Person p1(age, age2);
cout << p1.m_A << endl;
Person p2(20, 30);
Person p3 = p1 + p2;
cout << p3.m_A <<"\t"<< p3.m_B << endl;
return 0;
}
class Person
{
public:
int m_A;
int m_B;
//void operator<<( cout) // 无法运用成员函数重载左移运算符
};
ostream & operator << (ostream& cout, Person& p)// 运用全局函数重载左移运算符
{
cout << "m_A:" << p.m_A << " m_B:" << p.m_B;
return cout;
}
int main()
{
Person P;
P.m_A = 10;
P.m_B = 10;
cout << P << "\thello world" << endl;
}