在派生类中重载运算符

时间:2011-04-15 15:33:18

标签: c++ operator-overloading

如果我需要在派生类中使用它们,我是否需要重新定义所有带派生类型的重载运算符?

以下代码编译良好:

class Point {

public:

    Point(int X = 0, int Y = 0):x(X), y(Y) {}

    virtual ~Point() {}

    Point operator +(Point &rhs) {
        return Point(x + rhs.x, y + rhs.y);
    }

protected:
    int x, y;
};

class Vector : public Point {

public:

    Vector(int X, int Y) : Point(X, Y) {}

    ~Vector() {}

    Vector operator +(Vector &rhs) {
        return Vector(x + rhs.x, y + rhs.y);
    }
};

int main()
{
    Vector v1(1, 2);
    Vector v2(3, 2);

    Vector v3 = v2 + v1;
}

但是从我读过的内容来看,

C ++ Primer 4th Ed。第15.5.3节。

  

如果派生类想要全部制作   可用的重载版本   通过它的类型,它必须要么   重新定义所有这些或不重新定义。

引用“none of them”的部分是否在这里有意义?

3 个答案:

答案 0 :(得分:6)

Overloading operators in derived class from IBM.

  

A类中名为f的成员函数   将隐藏名为f in的所有其他成员   A的基类,不管是什么   返回类型或参数。该   以下示例演示了这一点:

struct A {
  void f() { }
};

struct B : A {
  void f(int) { }
};

int main() {
  B obj_B;
  obj_B.f(3);
//  obj_B.f();
}
  

编译器不允许   函数调用obj_B.f()因为   声明void B :: f(int)有   隐藏A :: f()。

     

过载而不是隐藏a   一个基类A的函数   派生类B,你介绍一下   函数名称的范围   B带有使用声明。该   以下示例与之相同   前一个例子,除了使用   声明使用A :: f:

struct A {
  void f() { }
};

struct B : A {
  using A::f;
  void f(int) { }
};

int main() {
  B obj_B;
  obj_B.f(3);
  obj_B.f();
}

因此,如果不重载所有这些,则只使用重载函数。

答案 1 :(得分:6)

这意味着如果Point有多个operator+(),并且您只重新定义了其中一个,那么只有那个可以在派生类中访问;其他重载将被隐藏。如果在派生类中声明 no operator+(),那么所有父类都可用;如果您在派生类中声明任何,则父类的 none 可用。

有意义吗?这种情况很好:父母声明一个,然后重新定义那个。没问题。但是,如果父级声明了两个,那么你的子类只能声明一个,只能访问那个。

答案 2 :(得分:2)

在C ++中,跨范围没有重载派生类范围不是此一般规则的例外。

Derived和Base类之间没有重载解析。一个例子:

class B
{
    public:
    int func1(int i)
    {
        cout<<"B::func1()";
        return i+1;
    }
};



class D : public B
{
    public:
    double func1(double d)
    {
        cout<<"D::func1()";
        return d+1.3;
    }
};

int main ()
{
    D *pd = new D;

    cout << pd->func1(2)  <<endl;
    cout << pd->func1(2.3)<<endl;

    return 0;
}

输出结果为:

D::func1()3.3
D::func1()3.6

同样的规则也适用于运营商成员函数,毕竟它们也是成员函数!

因此,在代码示例中,如果Point有多个operator+(),并且您在Derived类中重新定义了相同的运算符,那么派生类的对象只能访问该派生类运算符,因为该版本函数hides的其他基类版本operator+() 如果不重新定义派生类中的operator+(),则operator+()的父类版本都不会被隐藏,因此可以通过Derived类的对象访问。

因此声明:
If a derived class wants to make all the overloaded versions available through its type, then it must either redefine all of them or none of them.

此外,请注意,overloadingoverridingfunction hiding有三个词,它们有时会互换误用,但它们都有不同的含义。