Re: MI and clone()
* Joshua Maurice:
On Feb 23, 2:42 pm, Noah Roberts <d...@reply.com> wrote:
I'm having a very weird problem here that's apparently caused by MI
and/or virtual inheritance that I'd like help with. I finally managed
to get the problem to appear in small form. I'll leave the code at the
end so I can explain some things more deeply before hand.
[snip example with code]
The last time I checked, MSVC does not support covariant return types
with multiple inheritance. It actually gave me compiler errors IIRC,
saying something like "ambiguous type".
Noah may try the following code to work around the covariance issue:
<code>
#include <string>
#include <iostream>
class base {
protected:
virtual base * virtual_clone() const = 0;
public:
virtual void do_x() { std::cout << "base::do_x()\n"; }
virtual int * value() = 0;
virtual ~base() {}
base* clone() const { return virtual_clone(); }
};
class sub_base1
: public virtual base
{
public:
virtual void do_x() { std::cout << "sub_base1::do_x()\n"; }
};
class sub_base2
: public virtual base
{
public:
virtual void do_x() { std::cout << "sub_base2::do_x()\n"; }
};
class derived
: public sub_base1
, public sub_base2
{
protected:
virtual base * virtual_clone() const { return new derived; }
public:
virtual void do_x() { std::cout << "derived::do_x()\n"; }
derived* clone() const
{ return dynamic_cast<derived*>( virtual_clone() ); }
int * value() { return 0; }
};
class sub_base3
: public sub_base1
{
public:
void do_x()
{
std::cout << "sub_base3::do_x() -> " << *value() << "\n";
}
sub_base3* clone() const
{ return dynamic_cast<sub_base3*>( virtual_clone() ); }
};
class derived2
: public sub_base3
{
protected:
virtual base * virtual_clone() const { return new derived2(*this); }
public:
void do_y() {}
derived2 * clone() const
{ return dynamic_cast<derived2*>( virtual_clone() ); }
int * value() { return val; }
derived2(int * v) : val(v) {}
private:
int * val;
};
int main()
{
int x = 5;
derived2 d(&x);
d.do_x();
//d.virtual_clone()->do_x();
base * b = &d;
b->do_x();
base * b2 = b->clone();
b2->do_x();
sub_base3 * sb3 = dynamic_cast<sub_base3*>(b2);
sb3->do_x();
sub_base3 * sb32 = sb3->clone(); // this call doesn't explode.
sb32->do_x();
}
</code>
Cheers & hth.,
- Alf