做会计网站的流程,南昌网站建设公司效果,网站后台管理系统地址,网站开发笔记本目录
一.继承与友元的关系
二.继承与静态成员的关系
先回顾一下静态成员变量#xff1a;
运行TestPerson()函数#xff1a;
测试案例2#xff1a;
三.练习题#xff1a; 一.继承与友元的关系 友元关系不能被继承#xff0c;也就是说父类中的友元函数不能访问子类私…目录
一.继承与友元的关系
二.继承与静态成员的关系
先回顾一下静态成员变量
运行TestPerson()函数
测试案例2
三.练习题 一.继承与友元的关系 友元关系不能被继承也就是说父类中的友元函数不能访问子类私有和保护成员
class Student;
class Person{
public://友元声明friend void Display(const Person p, const Student s);
protected:string _name; // 姓名
};class Student : public Person{
public://...
protected:int _stuNum; // 学号
};void Display(const Person p, const Student s){cout p._name endl;//cout s._stuNum endl; //报错除非让子类中也使用友元声明
}int main(){Person p;Student s;Display(p, s);return 0;
} 如上图友元函数Display只在父类中声明过所以友元函数可以访问父类的成员变量Student虽然为Person的子类但是友元是不会被继承下来的也就是说父辈那一代是朋友关系但并不意味着父辈的子女与其也是朋友关系。 想让子类也能使用父类的友元函数需要在子类中也加入友元声明 二.继承与静态成员的关系 先回顾一下静态成员变量 1.它并不在类对象中存放它在静态区。 2.而且静态成员变量的创建在类内定义是在该类的外面定义定义时需要进行初始化赋值 3.一个类对象被创建时类对象中只有类的成员变量(静态成员变量除外) 4.成员函数不在类对象中 5.类对象的大小是根据类的成员变量规定的大小 总之静态成员变量是被所有类对象所共享的它只有一份。 class Person{
public:Person() { _count; }void Print() {//_name zzz;cout Print()函数 endl;}
public:string _name; // 姓名int _age;static int _count; // 统计人的个数。
};
//父类的静态成员变量
int Person::_count 0;//子类
class Student : public Person{
protected:int _stuNum; // 学号
};//孙子类
class Graduate : public Student{
protected:string _seminarCourse; // 研究科目
};void TestPerson(){Student s1;Student s2;Student s3;Graduate s4;cout 人数 : Person::_count endl;Student::_count 0;cout 人数 : Person::_count endl;
} 在父类Person的构造函数中每调用一次构造函数静态成员变量_count的值就会加1。 现如今有一个继承父类的子类和一个继承子类的孙子类。 测试函数中创建了四个对象该静态成员变量的值为多少 运行TestPerson()函数 通过结果的运行可知_count的值为4 原因前三个对象的创建自然不必说都是调用自家类的构造函数而对于孙子类Graduate的对象创建它虽然是继承自子类Student但是Student也是继承于Person类它们之间有血缘关系那么孙子类的对象创建自然也离不开父类的构造函数 测试案例2 运行结果: 通过结果可知父类对象与子类对象的_count是同一份无论是值还是地址都完全相同所以推断结论父类的静态成员变量会被子类所继承子类使用的_count与父类的是同一个_count 而且只要一方将静态成员值修改了那么只要与该静态成员有关的类所对应的值也都会变。 三.练习题
class Person{
public:Person() { _count; }void Print() {cout Print()函数 endl;}
public:string _name; // 姓名int _age;static int _count; // 统计人的个数。
};
//父类的静态成员变量
int Person::_count 0;void Test3() {Person *ptrnullptr;//代码1 cout ptr-_name endl;//代码2cout ptr-_age endl;//代码3cout ptr-_count endl;//代码4ptr-Print();
}int main(){Test3();
} 在Test3()函数中执行以下每一条代码时结果是什么 //代码1 cout ptr-_name endl; //代码2 cout ptr-_age endl; //代码3 cout ptr-_count endl; //代码4 ptr-Print(); 考题解析 代码1的结果会出现异常,因为Person类创建的对象是指针类型的一开始指针对象被初始化为空该指针对象ptr中的成员变量_name值也是空的所以当ptr访问它的成员变量_name时会出错(空指针访问成员变量会异常) 代码2的结果也是异常与代码1性质相同都是空指针访问了其成员变量。 代码3结果正确因为静态成员变量并不在父类对象ptr中它是在静态区存放。 代码4结果正确因为成员函数Print也不在父类对象ptr中况且在成员函数中并没有访问其成员变量(并没有发生空指针访问成员变量的行为)所以该对象访问成员函数行为无异常。 强调类对象中只存储非静态成员变量所以类对象的大小由类所拥有的成员变量所决定。并且类对象不存储成员函数也不存储静态成员变量。 若是父类的Print函数中访问了成员变量 那么 Person *ptrnullptr; //代码4 ptr-Print(); 代码4的运行就如同上面的代码1的结果一样运行异常报错ptr为空虽然访问了成员函数这一步没有报错但进入到成员函数体运行其语句时发现执行了_name“zzz”;语句该语句相当于this-_name访问成员变量类对象访问成员函数就是将该对象的地址传给类的this指针此时this指针相当于是空指针空指针访问成员变量报错