2011-04-15 76 views
8

如果我需要在派生類中使用它們,我是否需要重新定義所有具有派生類型的重載運算符?在派生類中重載運算符

下面的代碼編譯好:

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++入門第四版。第15.5.3節。

如果一個派生類希望通過它的類型,使所有 提供 重載版本,那麼它必須是 重新定義所有的人或沒有。

報價單「none of them」的部分是否有意義?

回答

6

這意味着如果Point有多個operator+(),並且您只重新定義了其中一個,那麼只有那個可以在派生類中訪問;其他重載將被隱藏。如果你在派生類中聲明operator+(),那麼所有的父類都是可用的;如果您在派生類中聲明任意,則可以使用父代的

有意義嗎?這種情況很好:父母聲明一個,然後重新定義那個。沒問題。但是,如果父母聲明瞭兩個,那麼你的孩子只能聲明一個,只能訪問那個孩子。

5

Overloading operators in derived class from IBM.

名爲F IN A類 將隱藏名爲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(),因爲 聲明無效B的:: F(INT)已 隱藏答: :F()。

過載,而不是隱藏在一個 派生類乙基類A的 功能,便增加了該函數的 名字進入 B與using聲明的範圍。該 下面的例子是一樣的使用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

嘿,你認爲可以引用其他人的內容嗎?似乎是版權問題給我。 – 2011-04-15 15:41:07

+0

@Ernest:我沒有創建C++語言,所以我不得不引用一些東西。看到類似的元問題:http://meta.stackexchange.com/questions/46448/answers-with-external-references-should-they-not-be-added-to-answers-and-perhap – 2011-04-15 15:59:18

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+(),你重新定義在派生類中的同一運營商則只有派生類運營商將是派生類的對象訪問,因爲該版本的功能​​其他基地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有三個方面是鬆散誤用互換,但有時他們都有不同的意思。