1.5.1 友元函数
#include <iostream> using namespace std; class Test { friend void show(Test &t); private: int m_a; public: Test() { m_a =100; } void show() { cout<<m_a<<endl; } }; void show(Test &t) { cout<<t.m_a<<endl; } int main(int argc, char const *argv[]) { Test t1; show(t1); return 0; }
1.5.2 友元类
#include <iostream> using namespace std; class A { friend class B; //友谊具有单向性 private: int m_a; public: A() { m_a = 100; } void print(B &b) { cout<<b.m_b<<endl; } }; class B { public: void print(A &a) { cout<<a.m_a<<endl; } private: int m_b; }; int main(int argc, char const *argv[]) { A a1; B b1; b1.print(a1); return 0; }
二 继承和派生
2.1 概念
继承可以理解为一个类从另一个类中获取成员变量和成员方法的过程,例如类B继承于类A,那么B就拥有A中所有的成员变量和方法,被继承的类称为父类或者基类,继承的类称为子类或者派生类
2.2 继承的语法
#include <iostream> #include <cstring> using namespace std; class Person //父类或者基类 { //private: protected: char m_name[32]; int m_age; public: Person() { strcpy(m_name,"张三"); m_age = 18; } }; class Student:public Person //子类或者派生类 { private: int m_id; public: Student(int id) { m_id = id; } void show() { cout<<"m_name = "<<m_name<<" m_age = "<<m_age<<" m_id = "<<m_id<<endl; } }; int main(int argc, char const *argv[]) { Student s1(1000); s1.show(); return 0; }
2.3 继承的权限
<1> 公有继承:基类中的所有属性原来具有什么样的权限,在派生类中保持不变,基类中的私有属性在派生类中不能访问。 <2> 保护继承:基类中的public在派生类中具有保护属性,其它不变,基类中的私有属性在派生类中不能访问。 <3> 私有继承:基类中public和protected都变成私有属性,基类中的私有属性在派生类中不能访问。
#include <iostream> using namespace std; class TestA { private: int m_a; protected: int m_b; public: int m_c; }; class TestB:private TestA //私有继承 { /* private: //不可访问 int m_a; private: int m_b; private: int m_c; */ public: void test() { //m_a++; this->m_b++; this->m_c++; } }; class TestC:protected TestA //保护继承 { /* private: int m_a; //不可访问 protected: int m_b; protected: int m_c; */ public: void test() { //m_a++; this->m_b++; this->m_c++; } }; class TestD:public TestA //公有继承 { /* private: //不可访问 int m_a; protected: int m_b; public: int m_c; */ public: void test() { //m_a++; this->m_b++; this->m_c++; } }; int main(int argc, char const *argv[]) { TestB b1; //b1.m_c = 1; TestD d1; d1.m_c = 1; return 0; }
2.4 继承模型
#include <iostream> using namespace std; class Person { public: int m_age; }; class Student:public Person { public: int m_id; }; int main(int argc, char const *argv[]) { Student s1; cout<<sizeof(s1)<<endl; cout<<&s1<<endl; cout<<&s1.m_age<<endl; cout<<&s1.m_id<<endl; return 0; }
2.5 继承中的构造
类的构造函数不能被继承,因为即使继承了,基类构造函数的名字和派生类也不一样,不能成为派生类的构造函数 为了初始化基类成员,需要在派生类的构造函数的初始化列表里面显示调用基类的构造函数。
#include <iostream> #include <cstring> using namespace std; class Person { protected: char name[32]; int age; public: Person(const char *n,int a) { cout<<"Person的有参构造函数"<<endl; strcpy(name,n); age = a; } ~Person() { cout<<"Person的析构函数"<<endl; } }; class Date { private: int m_year; int m_month; int m_day; public: Date(int y,int m,int d) { cout<<"Date有参构造函数"<<endl; m_year = y; m_month = m; m_day = d; } ~Date() { cout<<"Date的析构函数"<<endl; } }; class Student:public Person { private: Date birth; int id; public: //当基类没有提供无参构造函数的时候,派生类需要通过对象初始化列表来传参 Student(int i):Person("aaa",23),birth(1997,1,1) { cout<<"Student的构造函数"<<endl; id = i; } void show() { cout<<name<<" "<<age<<" "<<id<<endl; } ~Student() { cout<<"Student的析构函数"<<endl; } }; int main(int argc, char const *argv[]) { Student s1(1000); s1.show(); return 0; }
2.6 const修饰成员函数
#include <iostream> using namespace std; class Student { private: char *m_name; int m_age; float m_score; public: Student(char *n,int a,float s); void show(); char *GetName() const; int GetAge() const; float GetScore() const; }; Student::Student(char *n,int a,float s):m_name(n),m_age(a),m_score(s) { } void Student::show() { cout<<m_name<<"的年龄是"<<m_age<<",成绩是"<<m_score<<endl; } char* Student::GetName() const //成员函数必须在声明和定义处都加上const { return m_name; } int Student::GetAge() const { //m_age++; //常成员函数修饰只读成员变量 return m_age; } float Student::GetScore() const { return m_score; } int main(int argc, char const *argv[]) { Student s1("zhangsan",12,98); s1.show(); return 0; }
2.7 同名成员
基类和派生类中出现同名函数(原型相同)时,默认调用派生类中的成员,基类中的成员函数会被隐藏
#include <iostream> using namespace std; class TestA { private: int a; public: void show() { cout<<"this is TestA"<<endl; } }; class TestB:public TestA { private: int b; public: void show() { cout<<"this is TestB"<<endl; } }; int main(int argc, char const *argv[]) { TestB b1; b1.show(); //同名,默认调用派生类成员函数 b1.TestA::show(); return 0; }
2.8 继承中的static关键词
如果在基类中定义了静态成员变量,则该静态成员变量将被所有的派生类共享
#include <iostream> using namespace std; class Person { public: static int count; public: Person() { count++; } }; int Person::count = 0; class Student:public Person { }; int main(int argc, char const *argv[]) { Student s1; Student s2; Student s3; Student s4; Student s5; Person p1; Person p2; cout<<Person::count<<endl; cout<<Student::count<<endl; return 0; }