Boost logo

Boost Users :

From: Khandelwal, Amit (amit.khandelwal_at_[hidden])
Date: 2008-06-27 09:24:33


It all seems to make sense now. In the paper only diamond inheritance was discussed. When I was playing around with the code I may have constructed a diamond inheritance which led to that problem. Your explanation has cleared things up for me. Appreciate your response.

I have one final question.

If I define class C as below everything compiles correctly.

class C : public A {
    virtual CloneableBase * doClone() const {
    }
};

However, if I define it as described in the post I get the following error.

clone2.cpp:33: sorry, not implemented: adjusting pointers for covariant returns
clone2.cpp:33: sorry, not implemented: adjusting pointers for covariant returns
clone2.cpp:33: sorry, not implemented: adjusting pointers for covariant returns

class C : public A {
    virtual A* doClone() const {
    }
};

////////////////////////////////////////////////////////////////////////////////////////////////
#include <memory>

class CloneableBase {
public:
        virtual ~CloneableBase() {};

protected:
        virtual CloneableBase* doClone() const = 0 ;
};

template < typename Derived >
class Cloneable : public virtual CloneableBase {
public:
        typedef std::auto_ptr<Derived> AutoPtr;
        AutoPtr clone() const {
            return AutoPtr( dynamic_cast<Derived *>( doClone()) );
        }
};

template < typename Derived >
class NaturallyCloneable : public virtual CloneableBase {
protected:
    
        virtual CloneableBase* doClone() const {
            return new Derived( dynamic_cast< const Derived& >(*this) );
        }
};

class A : public Cloneable<A> {};
class B : public A, public NaturallyCloneable<B> {};

class C : public A {
    virtual A* doClone() const {
            return new C;
    }
};

int main() {
}

-----Original Message-----
From: boost-users-bounces_at_[hidden] [mailto:boost-users-bounces_at_[hidden]] On Behalf Of Daniel Krügler
Sent: Friday, June 27, 2008 5:21 AM
To: boost-users_at_[hidden]
Subject: Re: [Boost-users] shared_ptr invalid covariant return type

Khandelwal, Amit wrote:
> I am reading through the paper by B. Strousstrup on multiple inheritance and this is what is says.
>
> A class can have an arbitrary number of virtual base classes.
> One can cast from a derived class to a virtual base class, but not
> from a virtual base class to a derived class. The former involves
> following the virtual base pointer; the latter cannot be done given the information available at run time.

[Sorry for my late answer, yesterday I was out-of-office basically the complete day.]

Correct, it cannot be done for the general case due to potential ambiguity ("path-split"). But in can be done, if the dynamic_cast mechanism follows a unique path.

> Storing a ''back-pointer'' to the enclosing object(s) is non-trivial
> in general and was considered unsuitable for C++ as was the
> alternative strategy of dynamically keeping track of the objects ''for
> which'' a given member function invocation operates. The uses of such
> a back-pointer mechanism did not seem to warrant the added implementation complexity, the extra space required in objects, and the added run-time cost of initialization.
>
> class Cloneable : public virtual CloneableBase { .. }
>
> As per B. Strousstrup we cannot do it. Am I missing something obvious?

It be done, but there are exceptions, where it cannot be done.
For example there is no problem in the quoted cases:

class A : public Cloneable<A> {}; // abstract base for B and C class B : public A, public NaturallyCloneable<B> {}; class C : public A {
     virtual A* doClone() const {
             return new C;
     }
};

The reason is because CloneableBase is an abstract class, so during the
doClone() call of the clone function in Cloneable you will invoke
doClone() of an even more derived class as Cloneable itself is.
The result of doClone() will be a CloneableBase* to this derived object. The dynamic_cast attempty now to find this derived class and in many cases this search will be successful, see e.g. this extended example from [expr.dynamic.cast]/9:

class A { virtual void f() {} };
class B { virtual void g() {} };
class D : public virtual A, private B { }; class E : public D, public B { }; class F : public E, public D { };

int main() {
   F f;
   A* ap = &f; // succeeds: finds unique A
   D* dp = dynamic_cast<D*>(ap); //#1 fails: yields 0
                  // f has two D subobjects
   F* fp = dynamic_cast<F*>(ap); //#2
   E e;
   ap = &e;
   E* ep = dynamic_cast<E*>(ap); //#3
}

#1 fails, because via ap you can find two different D subobjects.

#2 and #3 both succeed, because there is only *one* object F that can be found and similar for the E object.

The rules for these cases are described in [expr.dynamic.cast]/8, which handle the runtime check of dynamic_cast.

> I have also seen the following error - something expected ..
>
> cannot convert from base `CloneableBase' to derived type `A' via
> virtual base `CloneableBase

Please provide a concrete example, currently I do not see where this should apply for the finally provided solution via dynamic_cast.

Greetings from Bremen,

Daniel Krügler

_______________________________________________
Boost-users mailing list
Boost-users_at_[hidden]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

This message is intended only for the personal and confidential use of the designated recipient(s) named above. If you are not the intended recipient of this message you are hereby notified that any review, dissemination, distribution or copying of this message is strictly prohibited. This communication is for information purposes only and should not be regarded as an offer to sell or as a solicitation of an offer to buy any financial product, an official confirmation of any transaction, or as an official statement of Lehman Brothers. Email transmission cannot be guaranteed to be secure or error-free. Therefore, we do not represent that this information is complete or accurate and it should not be relied upon as such. All information is subject to change without notice.

--------
IRS Circular 230 Disclosure:
Please be advised that any discussion of U.S. tax matters contained within this communication (including any attachments) is not intended or written to be used and cannot be used for the purpose of (i) avoiding U.S. tax related penalties or (ii) promoting, marketing or recommending to another party any transaction or matter addressed herein.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net