继承和多态问题全解析

#define _CRT_SECURE_NO_WARNINGS 1


//继承:
//private和protected的区别?
//在类外如果想使用类中的成员,只能直接使用public类型的,protected和private都是不能访问的。
//对于类外使用而言,这两个是完全相同的.
//但是在基类的派生类中, 可以直接访问继承而来的protected成员, 但是不能访问private限制的成员.
//所以在派生类中, 可以访问基类继承而来的public和proected两种类型的成员.
//在public公有派生下, 继承而来的成员访问权限不变.protected派生下, public和protected都变成protected,
//private派生下, 所有的继承下来都是private了.


//#include<iostream>
//#include<stdlib.h>
//#include<string>
//using namespace std;
//
//class Person
//{
//public:
// void Display()
// {
// cout << _name << endl;
// }
//
//protected:
// string _name;//姓名
//};
//
//class Student:public Person
//{
//protected:
// int _num;  //学号
//};
//
//void Test()
//{
// Person p;
// Student s;
// //1,子类对象可以赋值给父类对象
// p = s;
//
// //2,夫类对象不能赋值给子类对象
// //s1 = p1;
//
// //3,父类的指针/引用可以指向子类对象
// Person *p1 = &s;
// Person &r1 = s;
//
// //4,子类的指针/引用不能指向父类对象(通过强转科完成)
// Student *p2 = (Student *)&p;
// Student &r2 = (Student&)p;
//}
//int main()
//{
// Test();
// system("pause");
// return 0;
//}




继承体系中的作用域
1,在继承体系中基类和派生类都有独立的作用域
2,子类和父类中有同名成员,子类成员将屏蔽父类对成员的直接访问。(若要访问基类::基类成员)
//#include<iostream>
//#include<stdlib.h>
//#include<string>
//using namespace std;
//
//class Person
//{
//public:
// Person(const char* name = "", int id = 0)
// :_name(name)
// , _num(id)
// {}
//
//protected:
// string _name;//姓名
// int _num;    //身份证号
//};
//
//class Student:public Person
//{
//public:
// Student(const char* name, int id, int stuNUM)
// :Person(name, id)
// , _num(stuNUM)
// {}
// void Display()
// {
// cout << "姓名:" << _name << endl;
// cout << "身份证号:" << Person::_num << endl;//访问父类加上作用域
// cout << "学号:" << _num << endl;//自动忽略父类成员
// }
//protected:
// int _num;  //学号
//};
//
//void Test()
//{
// Student s("qingdou", 123456789, 7);
// s.Display();
//}
//int main()
//{
// Test();
// system("pause");
// return 0;
//}




//类的成员函数
//#include<iostream>
//#include<stdlib.h>
//#include<string>
//using namespace std;
//
//class Person
//{
//public:
// Person(const char* name)//构造
// :_name(name)
// {
// cout << "Person()" << endl;
// }
//
// Person(const Person& p)//拷贝构造
// :_name(p._name)
// {
// cout << "Person(const Person& p)" << endl;
// }
//
// Person&operator=(const Person& p)//赋值运算符的重载
// {
// cout << "Person&operator=(const Person& p)" << endl;
// if (this != &p)//判断是否是自赋值
// {
// _name = p._name;
// }
// return *this;
// }
// ~Person()
// {
// cout << "~Person()" << endl;
// }
//protected:
// string _name;//姓名
//};
//
//class Student:public Person
//{
//public:
// Student(const char* name, int num)//构造
// :Person(name)
// , _num(num)
// {
// cout << "Student()" << endl;
// }
// Student(const Student& s)//拷贝构造
// :Person(s)
// ,_num(s._num)
// {
// cout << "Student(const Student& p)" << endl;
// }
// Student&operator=(const Student& s)//赋值运算符的重载
// {
// cout << "Student&operator=(const Student& s)" << endl;
// if (this != &s)//判断是否是自赋值
// {
// Person::operator=(s);
// _num = s._num;
// }
// return *this;
// }
// ~Student()
// {
// cout << "~Student()" << endl;
// }
// void Display()
// {
// cout << "姓名:" << _name << endl;
// cout << "学号:" << _num << endl;
// }
//protected:
// int _num;  //学号
//};
//
//void Test()
//{
// Student s1("qingdou",18);//构造
// s1.Display();
// cout << endl;
//
// Student s2(s1);//拷贝构造
// s2.Display();
// cout << endl;
//
// Student s3("range", 20);//赋值运算符
// s3.Display();
// s1.Display();
//}
//int main()
//{
// Test();
// system("pause");
// return 0;
//}




//单继承和多继承
//菱形继承存在二义性和数据冗余的问题
//#include<iostream>
//#include<stdlib.h>
//#include<string>
//using namespace std;
//
//class Person
//{
//public:
// string _name;//姓名
//};
//
//class Student:public Person
//{
//protected:
// int _num;  //学号
//};
//
//class Teacher :public Person
//{
//protected:
// int _id;  //职工编号
//};
//class Assisitant :public Student, public Teacher
//{
//protected:
// string _majiorCourse;//主修课程
//};
//void Test()
//{
// //访问时要指定是哪个父类的成员
// Assisitant a;
// a.Student::_name = "qingdou";
// a.Teacher::_name = "yyyyyy";
//}
//int main()
//{
// Test();
// system("pause");
// return 0;
//}




//虚继承
//虚继承解决了在菱形继承中子类对象包含多个父类对象的数据冗余和空间浪费问题
//
//虚函数&多态
//虚函数重写:当在子类中定义了一个完全与父类相同的虚函数时,则称子类的这个函数重写(也成覆盖)了父类的这个虚函数。
//多态:当使用基类的指针或者引用调用重写的虚函数时,当指向父类调用的就是父类的虚函数,指向子类的就是子类的虚函数。
//#include<iostream>
//#include<stdlib.h>
//#include<string>
//using namespace std;
//
//class Person
//{
//public:
// virtual void BuyTickets()
// {
// cout << "买票,全票" << endl;
// }
//};
//
//class Student:public Person
//{
//public:
// virtual void BuyTickets() //对父类的重写(覆盖)
// {
// cout << "买票,半票" << endl;
// }
//};
//
//void fun(Person& p)//多态:基类引用调用重写函数
//{
// p.BuyTickets();
//}
//
//void Test()
//{
// Person p;
// Student s;
// fun(p);//指向父类,调用父类的虚函数
// fun(s);//指向子类,调用子类的虚函数
//}
//int main()
//{
// Test();
// system("pause");
// return 0;
//}


//总结:
//1,派生类重写基类的虚函数实现多态,要求函数名,参数列表,返回值完全相同(协变除外)
//2,基类中定义了虚函数,在派生类中该函数始终保持虚函数的特性。
//3,只有类的成员函数才能定义为虚函数。
//4,静态成员函数不能定义为虚函数。
//5,如果在类外定义虚函数,只能在声明函数时加virtual,类外定义函数时不能加virtual。
//6,构造函数不能为虚函数,虽然可以将operator=定义为虚函数,但是最好不要,容易引起混淆。
//7,不要再构造函数和析构函数里面调用虚函数,因为在构造函数和析构函数中,对象是不完整的,可能会发生未定义行为。
//8,最好把基类的析构函数声明为虚函数。因为派生类的析构函数跟基类的析构函数名称不一样,但构成覆盖,这是因为编译器做了特殊处理。
//
//纯虚函数:
//在成员函数的形参后面写上 = 0,则成员函数为纯虚函数。包含纯虚函数的类叫做抽象类(接口类),抽象类不能实例化出对象。
//纯虚函数在派生类中重新定义以后,派生类才能实例化出对象。


//class Person
//{
// virtual void Dispaly() = 0;//纯虚函数
//protected:
// string _name;
//};




友元和继承:
友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员
//#include<iostream>
//#include<stdlib.h>
//#include<string>
//using namespace std;
//
//class Person
//{
//public:
// friend void Display(Person&p, Student&s);
//protected:
// string _name;
//};
//class Student :public Person
//{
//protected:
// int _stuNUM;
//};
//
//void Display(Person&p, Student&s)
//{
// cout << p._name << endl;
// cout << s._name << endl;//友元不继承
// cout << s._stuNUM << endl;
//}
//
//void Test()
//{
// Person p;
// Student s;
// Display(p, s);
//}
//int main()
//{
// system("pause");
// return 0;
//}




//继承与静态成员
//基类定义了static成员,则整个继承体系里面只有一个这样的成员,无论派生出多少个子类,都只有一个static成员实例。
//#include<iostream>
//#include<stdlib.h>
//#include<string>
//using namespace std;
//
//class Person
//{
//public:
// Person()
// {
// ++_count;
// }
//protected:
// string _name;
//public:
// static int _count;//统计人的个数
//};
//
//int Person::_count = 0;
//class Student :public Person
//{
//protected:
// int _stuNUM;//学号
//};
//
//class Graduate :public Student
//{
//protected:
// string _seminarCourse;//研究课程
//};
//
//void Display(Person&p, Student&s)
//{
//}
//
//void Test()
//{
// Student s1;
// Student s2;
// Student s3;
//
// Graduate s4;//也算在_count中
//
// cout << "人数" << Person::_count << endl;
//
// Student::_count = 0;
// cout << "人数" << Person::_count << endl;
// //整个体系中只有一个_count。
//}
//int main()
//{
// Test();
// system("pause");
// return 0;
//}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值