我有CharRow
类有这样的字段:
protected:
char* ptr;
int ROW_MAX_LENGTH;
并且有子类BigIntegerNumber(char数组)。 我的算子+在CharRow中:
virtual CharRow operator+ (CharRow row2)
{
int row1Length = this->getRowCurrentLength();
int row2Length = row2.getRowCurrentLength();
CharRow tempRow(row1Length + row2Length);
for(int i = 0; i < row1Length; i++){
tempRow.ptr[i] = this->ptr[i];
}
for(int i = 0; i < row2Length; i++){
tempRow.ptr[i + row1Length] = row2.ptr[i];
}
return tempRow;
}
我需要以多态方式调用operator+
?
BigIntegerNumber operator+ (BigIntegerNumber row2)
{
BigIntegerNumber temp(this->getRowCurrentLength() + row2.getRowCurrentLength());
temp = BigIntegerNumber::addValue(*this, row2);
return temp;
}
答案 0 :(得分:0)
虚拟operator +
can work in general,但要使其发挥作用,必须满足一些限制条件。
在你的情况下它不起作用的第一个原因是,操作员
BigIntegerNumber operator+ (BigIntegerNumber row2)
不是
的覆盖virtual CharRow operator+ (CharRow row2)
但它是重载(隐藏原始运算符而不是覆盖它)。
要使它成为覆盖,函数签名必须相同。即相同类型的参数(CharRow
而不是BigIntegerNumber
,最好通过const ref而不是值传递),以及相同或协变的返回类型。这些都不符合。
这样的事情有时通过使用“常规”虚函数来完成,其中接口引用作为参数,并通过调用这样的函数来实现非虚拟运算符。
在这种情况下,主要问题是返回参数,因为您无法将返回类型定义为按值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可用于按值返回多态类型,并转换为原始类型。但请注意,在这种情况下,涉及内存分配。
答案 1 :(得分:-1)
如果你想在BigIntegerNumber :: operator +()中调用CharRow :: operator +(),你可以这样做:
rI."REFCL||'_TEST'"