本文参考博客有 博客1 和 博客2,以及C++primer部分内容,感谢
面向对象
面向对象程序设计(Object-oriented programming,OOP)是种具有对象概念的程序编程典范,同时也是一种程序开发的抽象方针。
面向对象三大特征:封装、继承、多态
封装
分离类的实现与接口,从而隐藏了类的实现细节。在C++语言中,通过把实现部分设为private完成封装的任务。
继承
由一个已有的类(基类)定义一个新类(派生类)的编程技术。派生类将继承基类的成员。
基类(父类)–> 派生类(子类)
多态
当用于面向对象范畴时,多态性的含义是指程序能通过引用或指针的动态类型获取类型特定行为的能力。
多态是以封装和继承为基础的
C++多态分类及实现
(参考博客)
- 重载多态(Ad-hoc Polymorphism,编译期):函数重载、运算符重载
- 子类型多态(Subtype Polymorphism,运行期):虚函数
- 参数多态性(Parametric Polymorphism,编译期):类模板、函数模板
- 强制多态(Coercion Polymorphism,编译期/运行期):基本类型转换、自定义类型转换
子类型多态
/*********************************************************
*
* Subtype polymorphism is the ability
*
* to use derived classes through base class pointers and references.
*
*********************************************************/
#include<iostream>
#include"cats.h"
class Felid{
public:
virtual void meow() = 0;
};
class Cat : public Felid{
public:
void meow(){
std::cout<<"Meowing cat!"<<std::endl;
}
};
class Tiger : public Felid{
public:
void meow(){
std::cout<<"Meowing tiger!"<<std::endl;
}
};
class Ocelot : public Felid{
public:
void meow(){
std::cout<<"Meowing ocelot!"<<std::endl;
}
};
void do_meowing(Felid *cat){
cat->meow();
}
int main(){
Cat cat;
Tiger tiger;
Ocelot ocelot;
do_meowing(&cat);
do_meowing(&tiger);
do_meowing(&ocelot);
return 0;
}
参数多态
#include<iostream>
#include<string>
template<class T>
T max(T a, T b){
return a>b?a:b;
}
int main(){
std::cout<<::max(9, 5)<<std::endl;
std::string foo("foo"), bar("bar");
std::cout<<::max(foo, bar)<<std::endl;
return 0;
}
重载多态
#include<iostream>
#include<string>
int add(int a, int b){
return a+b;
}
std::string add(const char *a, const char *b){
std::string result(a);
result += b;
return result;
}
int main(){
std::cout<<add(5, 9)<<std::endl;
std::cout<<add("hello ", "world")<<std::endl;
return 0;
}
强制多态
//例1
#include<iostream>
class A{
int foo;
public:
A(int ffoo) : foo(ffoo){}
void giggidy(){
std::cout<<foo<<std::endl;
}
};
void moo(A a){
a.giggidy();
}
int main(){
moo(55);
}
//例2
#include<iostream>
class CrazyInt{
int v;
public:
CrazyInt(int i) : v(i) {}
operator int() const {return v;} //conversion from CrazyInt to int
};
void print_int(int a){
std::cout<<a<<std::endl;
}
int main(){
CrazyInt b = 55;
print_int(999); //prints 999
print_int(b); //prints 55
return 0;
}
静态多态(编译期/早绑定)
函数重载
class A
{
public:
void do(int a);
void do(int a, int b);
};
动态多态(运行期/晚绑定)
虚函数:用virtual修饰成员函数,使其成为虚函数
注意:
普通函数(非类成员函数)不能是虚函数
静态函数(static)不能是虚函数
构造函数不能是虚函数(因为在调用构造函数时,虚表指针并没有在对象的内存空间中,必须要构造函数调用完成之后才会形成虚表指针)
内联函数不能是表现多态性时的虚函数
总结
占坑