【Linux C++ 系列 】07 C++ OOP 面向对象(续)

举报
jackwangcumt 发表于 2022/07/04 20:58:32 2022/07/04
【摘要】 这一篇继续探讨C++面向对象编程中的多态(Polymorphism)特征,这里主要有2类多态 :编译时多态(包含函数重载和操作符重载)和 运行时多态(虚函数)的基本用法。

1 OOP编程


     C++是一门面向对象的编程语言,所谓的面向对象编程(Object Oriented Programming,OOP)是一种计算机编程架构。OOP作为当前主流编程语言的一种特征,可以实现软件工程的3个主要目标:
    01)重用性;
    02)灵活性;
    03)扩展性。
     另外,OOP编程的核心特征是类+对象+继承+多态+消息的有机组合,OOP可以模拟人类处理问题的思维方式,使得软件的开发方法与过程与问题的解决方案在逻辑上尽可能一致,即OOP可以把客观世界中的实体抽象为编程语言中的对象,而对象可以用类进行实例化。前面一篇重点介绍了OOP中的继承,网址为:https://bbs.huaweicloud.com/blogs/363638 ,感兴趣的可以查看。
      这一篇继续探讨C++面向对象编程中的多态(Polymorphism)特征,这里主要有2类多态 :

  • 编译时多态:包含函数重载和操作符重载 
  • 运行时多态 :虚函数

2 编译时多态示例


     C++ 编译时多态包含函数重载和操作符重载。所谓的函数重载就是函数名虽然相同,但是参数不同。而操作符重载,则可以对简单的符号进行定义,比如自定义类的实例对象可以进行四则运算。下面给出一个简单的C++编译时多态的示例:

#include <iostream>
using namespace std;

namespace myns {

    class Complex{

        private :
            int real, imag ;
        public :
            //function override
            Complex(int r = 0, int i = 0)  {
                real = r;   
                imag = i;
            }
            Complex(const Complex &c)  {
                real = c.real;   
                imag = c.imag;
            }
            ~Complex(){
                cout << " Complex Object Dispose " << endl;
            }
            //operate override
            Complex operator + (Complex& c1){
               Complex ret;
               ret.real = this->real + c1.real;
               ret.imag = this->imag + c1.imag;
               return ret;
            }
            Complex operator - (Complex& c1){
               Complex ret;
               ret.real = this->real - c1.real;
               ret.imag = this->imag - c1.imag;
               return ret;
            }
            void print(){
                if (imag == 0){
                    cout <<" " << this->real << endl;
                }else if (imag > 0){
                    cout <<" " << this->real << " + " << this->imag << "i" << endl;
                }else{
                    cout <<" " << this->real << " - " << -(this->imag) << "i" << endl; 
                }
                
            }
    }; 


}


int main()
{
    myns::Complex c1(2,1) ;
    c1.print();
    myns::Complex c2(c1) ;
    c2.print();
    myns::Complex c3 = c1 + c2 ;
    c3.print();
    myns::Complex c0 = c1 - c2 ;
    c0.print(); 
    myns::Complex c5(7,0) ;
    (c5 - c1 ).print(); 
	return 0;
}

     其中的构造函数 Complex(int r = 0, int i = 0) 和 Complex(const Complex &c)  就可以看作是函数的重载,在创建对象时,可以传入不同的参数。而Complex operator + (Complex& c1) 和 Complex operator - (Complex& c1) 则定义了操作符重载,这样就可以对Complex对象进行 + 和 - 操作。其中的~Complex()是析构函数,在销毁对象时自动调用。对于动态申请的内存等操作,则需要在析构函数中释放内存或者进行资源清理工作。

执行如下代码进行编译和执行:

g++ demo10.cpp -o demo10
./demo10

   输出结果如下所示:

 2 + 1i
 2 + 1i
 4 + 2i
 0
 5 - 1i
 Complex Object Dispose 
 Complex Object Dispose 
 Complex Object Dispose 
 Complex Object Dispose 
 Complex Object Dispose 
 Complex Object Dispose 

3 运行时多态示例


     C++ 编译时多态除了函数重载和操作符重载外,还有一种在运行时才能进行确定。这里需要采用虚函数,这个功能有点类似于Java中的接口,可以通过虚函数来约定接口,而让其他的对象对虚函数进行实现。下面给出一个简单的C++运行时多态的示例 : 

#include <iostream>
using namespace std;

namespace myns {

    class Shape{
        protected :
            double width, height ;
        public :
            Shape(double width , double height )  {
                //using this->width not using width
                this->width = width;
                this->height = height;
            }
            //pure virtual function
            virtual double getArea() = 0 ;
    }; 

    class Rect : public Shape{
        public :
            Rect(double width , double height ) : Shape(width , height) {
            }
            double getArea(){
                return width * height ;
            }       
    };

    class Tri : public Shape{
        public :
            Tri(double width , double height ) : Shape(width , height) {
            }
            double getArea(){
                return (width * height) / 2.0 ;
            }       
    };


}

int main()
{
    myns::Rect rect(2.5,2.0) ;
    cout << "Rect.getArea() -> " << rect.getArea() << endl ;
    myns::Shape* shp ;
    shp = &rect ;
    cout << "shp->getArea() -> " << shp->getArea() << endl ;
    myns::Tri tri(2.5,2.0) ;
    shp = &tri ;
    cout << "Tri.getArea() -> " << shp->getArea() << endl ;

	return 0;
}

通过虚函数,让继承自Shape的子类实现逻辑细节,且通过基类指针,可以在不同子类实例中进行运行时切换,并可以访问实现的函数。执行如下代码进行编译和执行:

g++ demo11.cpp -o demo11
./demo11

   输出结果如下所示:

Rect.getArea() -> 5
shp->getArea() -> 5
Tri.getArea() -> 2.5


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。