C++ 运算符重载和多态性

问题描述 投票:0回答:4

多态性和运算符重载会混合在一起吗?

没有指针就无法实现多态性,正如这个答案中所解释的那样,而且您也不能像这里所解释的那样使用指针进行运算符重载。 所以真的没有办法做到这一点,对吗?

c++ polymorphism operator-overloading
4个回答
7
投票

是的,有。你没有正确阅读答案。

这是一个简短的演示:

#include <iostream>
using namespace std;

struct X
{
    int value;
    virtual void operator += (int x)
    {
        value += x;
    }
};

struct Y : X
{
    virtual void operator += (int x)
    {
        value *= x;
    }
};

void do_stuff(X& x)
{
    x += 10;
    cout << "Final value " << x.value << endl;
}

int main()
{
    X x;
    x.value = 10;
    Y y;
    y.value = 10;
    do_stuff(x);
    do_stuff(y);

    return 0;
}

我并不是暗示这是一个好主意,或者它是实用的。这简直就是可能。


4
投票

简而言之:

运算符重载是一种静态多态性。

静态多态可以使用函数重载、运算符重载和

template
s来实现。

我认为你只考虑动态多态性(

virtual
之类的东西)。
另一方面,通常我们看不到重载运算符的
virtual
函数,但理论上它仍然是可能的。

更正:运行时(动态)多态性可以使用指针和引用来完成。


3
投票

首先,多态性适用于引用和指针。和 运算符重载与引用一起使用。所以没有问题 那个水平。

二元运算符存在潜在问题。直接语言 对运算符多态性的支持仅适用于左手 操作数。至于像二进制

+
这样的东西,从逻辑上讲, 期待双重派遣。虽然这可以实现,但有点 更复杂,特别是如果层次结构是开放的。

对于像二进制

+
这样的运算符,通常返回一个新对象,有 也是返回类型的问题。通常,这不能是 引用,因为没有具有适当类型的对象可供引用 到。像信封习语这样的模式已经被开发来处理 有了这个,但它们并不一定简单,而且它们往往有非常 显着的运行时开销。 或者 重载运算符返回一个 特殊类型,只保存它的参数,并且知道如何计算 请求时具有正确类型的值。


-1
投票

C++ 中的运算符重载可能涉及运行时多态性和编译时多态性,具体取决于其实现方式。

  1. 编译时多态性: 许多运算符重载在编译时就得到了解决。这包括与用户定义类型(例如类对象)一起使用时的

    +
    -
    *
    /
    等运算符。编译器在编译时根据操作数的类型生成具体操作的代码。

    class Complex {
    public:
        Complex operator+(const Complex& other) const {
            Complex result;
            result.real = this->real + other.real;
            result.imaginary = this->imaginary + other.imaginary;
            return result;
        }
    private:
        double real;
        double imaginary;
    };
    

    在此示例中,

    +
    运算符为
    Complex
    类重载。编译器在编译时根据操作数的类型生成加法运算的代码。

  2. 运行时多态性: 当操作符重载与虚函数结合使用时,它还可能涉及运行时多态性。例如,当您重载用于输出流的

    <<
    运算符并将其与多态类一起使用时,要调用的特定函数在运行时确定。

    class Shape {
    public:
        virtual void draw() const {
            // Base class implementation
        }
    };
    
    class Circle : public Shape {
    public:
        void draw() const override {
            // Derived class implementation
        }
    };
    
    std::ostream& operator<<(std::ostream& os, const Shape& shape) {
        shape.draw();  // Calls the appropriate draw() based on the object's actual type
        return os;
    }
    

    在此示例中,为基类

    <<
    重载了
    Shape
    运算符,并调用
    draw
    函数。实际执行的函数是在运行时根据对象的类型确定的。

因此,虽然某些运算符重载在编译时针对特定类型进行了解析,但其他运算符重载在与多态类和虚函数一起使用时可能涉及运行时多态性。关键是要理解具体的上下文以及运算符重载是如何实现的。

© www.soinside.com 2019 - 2024. All rights reserved.