专栏首页cwl_JavaC++-面向对象(五)

C++-面向对象(五)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/weixin_42528266/article/details/102753196

父类构造函数
  • 子类的构造函数默认会调用父类的无参构造函数
  • 如果子类的构造函数显式地调用了父类的有参构造函数,就不会再去默认调用父类的无参构造函数
  • 如果父类缺少无参构造函数,子类的构造函数必须显式调用父类的有参构造函数
#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;
}
VS的内存窗口

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java工具集-支持各种类型快速排序工具

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    cwl_java
  • 数据结构与算法-打印菱形算法

    cwl_java
  • Java工具集-验证码工具类

    cwl_java
  • Java中大量if...else语句的消除替代方案

    在我们平时的开发过程中,经常可能会出现大量If else的场景,代码显的很臃肿,非常不优雅。那我们又没有办法处理呢?

    攻城狮的那点事
  • 线性查找

      线性查找也叫顺序查找,这是最基本的一种查找方法,从给定的值中进行搜索,从一端开始逐一检查每个元素,直到找到所需元素的过程。   如果元素个数为 N,那么线性...

    IT可乐
  • Spring - AOP(10)

    使用动态代理解决上述问题 代理设计模式的原理:使用一个代理将对象包装起来,然后用该代理对象取代原始对象,任何对原始对象的调用都要通过代理,代理对象决定是否以及...

    桑鱼
  • java概念1

    public static void main(String[] args) {//其中[]也可以写在args后面,args也可以随便写成其他字母,例如asd...

    闵开慧
  • 回溯算法解迷宫问题(java版)

        以一个M×N的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计程序,对任意设定的迷宫,求出从入口到出口的所有通路。

    天涯泪小武
  • Java中多个ifelse语句的替代设计

    ifelse是任何编程语言的重要组成部分。但是我们编写了大量嵌套的if语句,这使得我们的代码更加复杂和难以维护。

    王知无
  • 浅谈程序设计中的位操作什么是位操作位操作的常用技巧位操作的应用,常见的算法题小结

    位操作是一种很底层的操作二进制数据的方法,虽然比较难掌握,但是有时候却有更高的效率和难以名状的优雅感。而且,在面试或者笔试中,考察基本的位操作应用越老越普遍,所...

    desperate633

扫码关注云+社区

领取腾讯云代金券