gpt4 book ai didi

时间:2019-03-08 标签:c++overloadingvirtual+operator

转载 作者:搜寻专家 更新时间:2023-10-31 00:43:44 25 4
gpt4 key购买 nike

#include <iostream>

class aa
{
public:
aa(){}

aa(aa& obj)
{
aa1 = obj.aa1;
}

virtual aa operator =(aa& obj)
{
aa1 = obj.aa1;
return (*this);
}

virtual aa operator +(aa& obj)
{
aa1 += obj.aa1;
return (*this);
}

int aa1;
};

class bb: public aa
{
public:
bb():aa(){}

bb(bb& obj)
{
bb1 = obj.bb1;
}

aa operator =(aa& obj)
{
aa::operator =(obj);
bb b1 = dynamic_cast<bb&>(obj);
bb1 = b1.bb1;
return (*this);
}

aa operator +(aa& obj)
{
aa::operator +(obj);
bb b1 = dynamic_cast<bb&>(obj);
bb1 += b1.bb1;
return (*this);
}

int bb1;
};


int main()
{
bb b1;
bb b2;

b1.bb1 = 1;
b1.aa1 = 1;

b2.bb1 = 2;
b2.aa1 = 2;

aa &a1 = b1;
aa &a2 = b2;

a1 = a2;
b1 = dynamic_cast<bb&>(a1);
b2 = dynamic_cast<bb&>(a2);

std::cout<<b1.aa1<<";"<<b1.bb1;

bb b3;
b3.bb1 = 3;
b3.aa1 = 3;

aa &a3 = b3;

aa &a4 = a2 + a3;
b3 = dynamic_cast<bb&>(a4);

return 0;
}

输出: 2;2然后它在 b3 = dynamic_cast<bb&>(a4); 行崩溃给出错误 std::bad_cast at memory location 0x0012fdbc..

我发现的原因是 a2+a3 的表达式结果作为 aa 类型的对象出现,在下一个语句中我们试图将其转换为无效的派生类型对象,因此导致异常。所以我的问题是我们能否实现上述意图即 aa &a4 = a2 + a3;上述功能有什么变化?

最佳答案

C++ 有单一调度(基于虚函数)。多态二元运算符不可避免地陷入“双重调度”的情况,因此不能仅通过简单的虚函数实现多态。

此外,由于您要返回一个值,因此每个子类信息都会丢失。

处理这种情况的更合适的方法是定义一个非多态句柄来实现操作并持有多态类型,将操作执行委托(delegate)给它们。

喜欢

class handle
{
public:
class aa;
class bb;

class root
{
public:
virtual ~root() {} //< required being this polymorphic
virtual root* clone()=0;

virtual handle add_invoke(const root& r) const=0; //resolve the 2nd argument
virtual handle add(const aa& a) const=0; //resolve the 1st argument
virtual handle add(const bb& a) const=0; //resolve the 1st argument
};

class aa: public root
{
public:
aa(...) { /*set vith a value */ }
aa(const aa& a) { /* copy */ }
virtual root* clone() { return new aa(*this); }

virtual handle add_invoke(const root& r) const
{ return r.add(*this); } //will call add(const aa&);

virtual handle add(const aa& a) const
{ return handle(new aa(.../*new value for aa with (aa,aa)*/)); }
virtual handle add(const bb& a) const
{ return handle(new bb(.../*new value for bb with(aa,bb)*/)); }
};

class bb: public root
{
public:
bb(...) { /*set vith a value */ }
bb(const bb& b) { /* copy */ }
virtual root* clone() { return new bb(*this); }

virtual handle add_invoke(const root& r) const
{ return r.add(*this); } //will call add(const bb&);

virtual handle add(const aa& a) const
{ return handle(new bb(.../*new value for aa with (bb,aa)*/)); }
virtual handle add(const bb& a) const
{ return handle(new bb(.../*new value for bb with (bb,bb)*/)); }
};

handle() :ps() {}
//support both copy (by clone) and move (by stole)
handle(const handle& s) :ps(s.ps? s.ps->clone(): nullptr) {}
handle(handle&& s) :ps(s.ps) { s.ps=nullptr; };
//assign by value, to force temporary assign
handle& operator=(handle h) { delete ps; ps=h.ps; h.ps=0; return *this; }
//cleanup
~handle() { delete ps; }

//the operator+
friend handle operator+(const handle& a, const handle& b)
{
return (b.ps && a.ps)? b.ps->add_invoke(*a.ps): handle();
//Note: manage also the a+b with one of `a` or `b` as null, if it make sense
}

private:
handle(root* p) :ps(p) {}

root* ps;
};

关于时间:2019-03-08 标签:c++overloadingvirtual+operator,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10186123/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com