📜  临时,包含,参数和强制多态性

📅  最后修改于: 2021-05-07 10:19:34             🧑  作者: Mango

当我们谈论C++中的多态时,我们听到以下四种类型:

详细讨论以下内容:

  1. 临时多态性,也称为重载

    临时多态性允许具有相同名称的函数对不同类型的行为有所不同。例如:
    +运算符将两个整数相加并连接两个字符串。

    可以通过在下面提到的代码中调用函数“ sum()”来更好地说明上面的示例:

    #include 
    using namespace std;
      
    int sum(int x, int y)
    {
        int c = x + y;
        return c;
    }
      
    string sum(const char* x, const char* y)
    {
        string summation(x);
        summation += y;
        return summation;
    }
      
    int main()
    {
        cout << sum(50, 20)
             << " :- Integer addition Output\n";
        cout << sum("Polymorphism", " achieved")
             << " :- String Concatenation Output\n";
    }
    
    输出:
    70 :- Integer addition Output
    Polymorphism achieved :- String Concatenation Output
    

    因此,通过调用两个具有相同名称的不同函数(参数类型不同)以执行多个操作,我们成功实现了Ad-hoc Polymorphism。

  2. 包容多态性,也称为子类型

    包含多态是通过基类指针和引用使用派生类的能力。这也称为运行时多态,因为编译器未在编译时定位函数的地址,而是取消引用了虚拟表中的右指针以在运行时调用函数。
    虚拟函数的概念(也称为动态链接)用于实现包含多态性。虚拟函数的使用允许根据要为其调用的对象的类型来选择要调用的函数。
    例如:
    为了实现这种多态技术,让我们考虑不同的文件,例如.jpg,.gif,.png文件。所有这些文件都属于“图像文件”类别。

    因此,它们可以表示为从Image Base Class派生的Class,并且可以重写display()纯虚函数。通过以下插图可以更好地理解上面的示例:

    #include 
    using namespace std;
      
    class Image {
      
    public:
        Image()
        {
        }
      
        virtual void display() = 0;
    };
    class Jpg : public Image {
    public:
        Jpg()
        {
        }
      
        void display()
        {
            cout << "JPG Image File" << endl;
        }
    };
      
    class Png : public Image {
    public:
        Png()
        {
        }
      
        void display()
        {
            cout << "PNG Image File" << endl;
        }
    };
      
    // Main function
    int main()
    {
        Image* img;
        Jpg jg;
        Png pg;
      
        // stores the address of Jpg
        img = &jg;
      
        // invoking display() func of Jpg
        img->display();
      
        // stores the address of Png
        img = &pg;
      
        // invoking display() func of Png
        img->display();
      
        return 0;
    }
    
    输出:
    JPG Image File
    PNG Image File
    

    因此,在上面的代码中,我们有两个不同的类,它们的函数具有相同的名称,但参数不同,但实现方式不同。

  3. 胁迫多态性,也称为铸造

    当对象或图元被转换为其他类型时,会发生强制多态。它可以是隐式的也可以是显式的。

    隐式转换是编译器本身的责任。
    例如:
    浮点f = 100
    (整数隐式提升为浮动)

    显式转换使用某些类型转换表达式,例如const_cast,dynamic_cast等。
    例如:
    当一个类为某种类型(例如“ int”)定义转换运算符,则可以在程序中任何需要整数类型数据的地方使用它。
    下图可以使您更容易理解:

    上面的插图可以在下面的代码的帮助下进一步阐明:

    #include 
    using namespace std;
      
    class IntClass {
        int num;
      
    public:
        IntClass(int a)
            : num(a)
        {
        }
      
        operator int() const
        {
            return num;
        } // conversion from User-defined type to Basic type
    };
      
    void show(int x)
    {
        cout << x << endl;
    }
      
    int main()
    {
        IntClass i = 100;
        show(746); // outputs 746
        show(i); // outputs 100
    }
    
    输出:
    746
    100
    

    使用IntClass引用代替整数类型参数,因此,很好地了解了Casting的概念。

  4. 参数多态性,也称为早期绑定

    参数多态性为将同一段代码用于不同类型提供了一种方法。它是通过使用模板来实现的。
    例如:
    为了加深对这种多态性的理解,让我们执行一个程序来查找两个整数或两个字符串中的更大的一个,

    #include 
    #include 
    using namespace std;
      
    template 
    temp greater(temp a, temp b)
    {
        if (a > b)
            return a;
        else
            return b;
    }
      
    int main()
    {
        cout << ::greater(55, 11) << endl;
      
        string str1("Early"), str2("Binding");
        cout << ::greater(str1, str2) << endl;
    }
    
    输出:
    55
    Early
    

    使用模板,可以使用不同类型的数据对同一函数进行参数化,但这需要在编译时自行确定,因此,该多态性被命名为。
    如果我们希望为指针实现这样的多态性,它将变成即席多态性。