版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
父类构造函数
- 子类的构造函数默认会调用父类的无参构造函数
- 如果子类的构造函数显式地调用了父类的有参构造函数,就不会再去默认调用父类的无参构造函数
- 如果父类缺少无参构造函数,子类的构造函数必须显式调用父类的有参构造函数
#include <iostream>
using namespace std;
//class Person {
// int m_age;
//public:
// Person() {
// cout << "Person()" << endl;
// }
// Person(int age) :m_age(age) {
// cout << "Person(int age)" << endl;
// }
//};
//
//class Student : public Person {
// int m_score;
//public:
// Student() {
// cout << "Student()" << endl;
// }
// Student(int age, int score) :m_score(score), Person(age) {
// cout << "Student(int age, int score)" << endl;
// }
//};
class Person {
int m_age;
public:
Person(int age) :m_age(age) {
cout << "Person(int age)" << endl;
}
};
class Student : public Person {
int m_score;
public:
Student() :Person(0) {
}
};
int main() {
Student student;
getchar();
return 0;
}
父类指针和子类指针
- 父类指针可以指向子类对象,是安全的,开发中经常用到(继承方式必须是public)
- 子类指针指向父类对象是不安全的
#include <iostream>
using namespace std;
class Person {
public:
int m_age;
};
// Student是一个Person
class Student : public Person {
public:
int m_score;
};
int main() {
// 学生是一个人
//Person *stu = new Student();
//stu->m_age = 10;
/*Student *p = (Student *) new Person();
p->m_age = 10;
p->m_score = 20;*/
getchar();
return 0;
}
多态
- 默认情况下,编译器只会根据指针类型调用对应的函数,不存在多态
- 多态是面向对象非常重要的一个特性
- 同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果
- 在运行时,可以识别出真正的对象类型,调用对应子类中的函数
- 多态的要素
- 子类重写父类的成员函数(override) 父类指针指向子类对象
- 利用父类指针调用重写的成员函数
#include <iostream>
using namespace std;
/*
面向对象的3大特性:
封装
继承
多态
重写(override):子类重写(覆盖)父类的方法
重载(overload)
*/
class Animal {
public:
virtual void run() {
cout << "Animal::run()" << endl;
}
};
class Dog : public Animal {
public:
void run() {
cout << "Dog::run()" << endl;
}
};
class ErHa : public Dog {
public:
void run() {
cout << "ErHa::run()" << endl;
}
};
int main() {
/*Animal *animal0 = new Animal();
animal0->run();
Animal *animal1 = new Dog();
animal1->run();
Animal *animal2 = new ErHa();
animal2->run();*/
Dog *dog0 = new Dog();
dog0->run();
Dog *dog1 = new ErHa();
dog1->run();
getchar();
return 0;
}
//class Animal {
//public:
// virtual void run() {
// cout << "Animal::run()" << endl;
// }
//};
//
//class Cat : public Animal {
//public:
// void run() {
// cout << "Cat::run()" << endl;
// }
//};
//
//class Dog : public Animal {
//public:
// void run() {
// cout << "Dog::run()" << endl;
// }
//};
//
//class Pig : public Animal {
//public:
// void run() {
// cout << "Pig::run()" << endl;
// }
//};
//int main() {
//
// Animal *animal = new Pig();
// animal->run();
//
// getchar();
// return 0;
//}
//void liu(Animal *animal) {
// animal->run();
// // ....
// // ....
// // ....
//}
//
//int main() {
// liu(new Dog());
// liu(new Cat());
// liu(new Pig());
//
// getchar();
// return 0;
//}
//void liu(Dog *dog) {
// dog->run();
// // ....
// // ....
// // ...
//}
//
//void liu(Cat *cat) {
// cat->run();
// // ....
// // ....
// // ...
//}
//
//void liu(Pig *pig) {
// pig->run();
// // ....
// // ....
// // ...
//}
虚函数
- C++中的多态通过虚函数(virtual function)来实现
- 虚函数:被virtual修饰的成员函数
- 只要在父类中声明为虚函数,子类中重写的函数也自动变成虚函数(也就是说子类中可以省略virtual关键字)
#include <iostream>
using namespace std;
class Animal {
public:
int m_age;
virtual void speak() {
cout << "Animal::speak()" << endl;
}
virtual void run() {
cout << "Animal::run()" << endl;
}
};
class Cat : public Animal {
public:
int m_life;
Cat() :m_life(0) {}
void speak() {
cout << "Cat::speak()" << endl;
}
void run() {
cout << "Cat::run()" << endl;
}
};
int main() {
cout << sizeof(Animal) << endl;
// cout << sizeof(Cat) << endl;
/*Animal *animal = new Animal();
Animal *cat1 = new Cat();
cat1->speak();
cat1->run();
Animal *cat2 = new Cat();
Animal *cat3 = new Cat();*/
Animal *animal1 = new Animal();
animal1->m_age = 10;
animal1->run();
Animal *animal2 = new Cat();
animal2->run();
getchar();
return 0;
}
虚表
#include <iostream>
using namespace std;
class Animal {
public:
int m_age;
virtual void speak() {
cout << "Animal::speak()" << endl;
}
virtual void run() {
cout << "Animal::run()" << endl;
}
};
class Cat : public Animal {
public:
int m_life;
Cat() :m_life(0) {}
void speak() {
// 先执行父类中的成员函数
Animal::speak();
// 再执行自己的一些操作
cout << "Cat::speak()" << endl;
}
void run() {
cout << "Cat::run()" << endl;
}
};
int main() {
/*Animal *animal1 = new Animal();
animal1->speak();
animal1->run();*/
Animal *animal2 = new Cat();
animal2->speak();
animal2->run();
getchar();
return 0;
}