虛擬operator +
can work in general,但是它的工作,一些制約因素必須得到滿足。
爲什麼它不會工作你的情況的第一個原因是,該操作
BigIntegerNumber operator+ (BigIntegerNumber row2)
不是覆蓋的
virtual CharRow operator+ (CharRow row2)
但其超載(隱藏原來的操作員而不是覆蓋它)。
因爲它是重寫,函數簽名必須是相同的。即相同類型的參數(CharRow
而不是BigIntegerNumber
,最好通過const ref傳遞比值),以及相同或協變的返回類型。這些都不符合。
這樣的事情有時是通過使用一個「常規」的虛函數來完成的,這個函數將接口引用作爲參數,並通過調用這樣的func來實現非虛函數。
在這種情況下,主要問題是返回參數,因爲您無法將返回類型定義爲按值CharRow
並實際返回BigIntegerNumber
(它將被切片爲返回類型)。您可能更喜歡operator +=
,它可以將參考返回給自己,從而能夠多形地工作。
爲operator +=
的例子(其不具有與返回值的類型的問題):
#include <iostream>
using namespace std;
struct Base
{
virtual Base& operator +=(const Base& other); // takes Derived as well for the virtual calls
};
struct Derived: Base
{
Derived& operator +=(const Base& other); // override - called via virtual
Derived& operator +=(const Derived& other); // overload - not called via virtual
// remove to always call the polymorphic version
};
Base& Base::operator +=(const Base& other)
{
cout << "Base::operator +=(Base)";
// beware this is slow!
const Derived* d = dynamic_cast<const Derived*>(&other);
if (d)
cout << " - called with Derived";
else
cout << " - called with Base";
cout << endl;
return *this;
}
Derived& Derived::operator +=(const Base& other)
{
cout << "Derived::operator +=(Base)";
// beware this is slow!
const Derived* d = dynamic_cast<const Derived*>(&other);
if (d)
cout << " - called with Derived";
else
cout << " - called with Base";
cout << endl;
return *this;
}
Derived& Derived::operator +=(const Derived& other)
{
cout << "Derived::operator +=(Derived)" << endl;
return *this;
}
int main()
{
Derived d1, d2;
Base b, b0;
Base& b1 = d1;
Base& b2 = d2;
d1 += d2; // Derived::operator +=(Derived)
b1 += d2; // Derived::operator +=(Base) - called with Derived
d1 += b1; // Derived::operator +=(Base) - called with Derived
b1 += b2; // Derived::operator +=(Base) - called with Derived
b += d2; // Base::operator +=(Base) - called with Derived
d1 += b; // Derived::operator +=(Base) - called with Base
b += b0; // Base::operator +=(Base) - called with Base
b1 += b; // Derived::operator +=(Base) - called with Base
return 0;
}
對於operator +
值傳遞結果類型的問題。但是,在C++中仍然不是不可能的,但是你需要使用某種包裝。這種包裝的一個例子:
#include <iostream>
#include <memory>
using namespace std;
struct Base;
struct Derived;
class BaseWrapper
{
shared_ptr<Base> _obj;
public:
explicit BaseWrapper(const shared_ptr<Base>& obj) : _obj(obj)
{}
template<class RESULT_T>
operator RESULT_T()
{
// throws if type not correct
return dynamic_cast<RESULT_T&>(*_obj);
}
Base& operator +=(const Base& other);
BaseWrapper operator +(const Base& other) const;
};
struct Base
{
virtual Base& operator +=(const Base& other); // takes Derived as well for the virtual calls
BaseWrapper operator +(const Base& other) const;
private:
virtual shared_ptr<Base> copy() const
{
return make_shared<Base>(*this);
}
};
struct Derived : Base
{
Derived& operator +=(const Base& other); // override - called via virtual
private:
virtual shared_ptr<Base> copy() const
{
return make_shared<Derived>(*this);
}
};
Base& BaseWrapper::operator += (const Base& other)
{
return *_obj += other;
}
BaseWrapper BaseWrapper::operator +(const Base& other) const
{
return *_obj + other;
}
BaseWrapper Base::operator +(const Base& other) const
{
BaseWrapper result(copy());
result += other;
return result;
}
int main()
{
Derived d1, d2;
Base b, b0;
Base& b1 = d1;
Base& b2 = d2;
b = b1 + b2; // add Derived + Derived, result is Derived (typed Base)
b = b0 + d1; // add Base + Derived, result is Base
// d1 = b0 + d1; // add Base + Derived, result is Base, throws bad_cast (cannot cast to Derived)
d1 = b1 + b2; // add Derived + Derived, result is Derived
return 0;
}
即,BaseWrapper可用於通過價值轉換返回多態型,並且具有與原始類型。但是請注意,在這種情況下涉及內存分配。
請嘗試創建一個[最小,完整和可驗證示例](http:// stackoverflow。com/help/mcve)並向我們展示,而不是脫離一些片段。並請[請閱讀如何提出好問題](http://stackoverflow.com/help/how-to-ask)。 –
[虛擬賦值運算符C++]的可能重複(http://stackoverflow.com/questions/669818/virtual-assignment-operator-c) – Garf365