I want to have a reference to the source object in the receiving object
after a copy (Copy ctr or assignment). I dont want the receiving object
to be able to modify contents in the copied object.

How should i do this?

Here is my first stab at a solution, but its not working.
Its the dynamic downcast from Base* to SubA* that fails when i run. I
want to use a dynamic cast since i sometimes need to do a runtime check
to see if an object is if a certain type. I need to do a downcast to be
able to check the values of the original (source) object.

So how can i have access to the source object, use it as the downcasted
subtype ,and restrict that access to be read-only.


class Base
{
public:
Base() : sourceObj(NULL) {}
virtual ~Base() {}

Base(const Base& other)
{
*this = other
}
Base& operator=(const Base& other)
{
sourceObj = &other;
return *this;
}

protected:
const Base* sourceObj;

}

class SubA : Base
{
public:
SubA() : Base() {}
~SubA() {}
SubA(const SubA& other) : Base(other) {}

int anAttribute;

void checkAttributeOfSource()
{
// Line below casts an error when run in MS VC++ .NET
SubA* a = dynamic_cast<SubA*>(sourceObj);
if (a->anAttribute = 1)
{
// do something
}
}
}

// ---- Main snippet --------
Base* aBase = new SubA();
// Line below casts an error when run in MS VC++ .NET
SubA* aSub = dynamic_cast<SubA*>(aBase);


// --- Scenario B
SubA a1.readFromdatabase();
SubA a2(a1);
a2.ReadFromClient();

// Here i want to be able to query values in a1 without modifying
a1
a2.CompareMeTosourceObject();

Re: How to access the source of a copied object by Ulrich

Ulrich
Mon Aug 22 04:35:17 CDT 2005

(F'up to microsoft.public.vc.language, OT in mpvs anyway.)

mats.g.friberg@datarutin.se wrote:
> I want to have a reference to the source object in the receiving object
> after a copy (Copy ctr or assignment). I dont want the receiving object
> to be able to modify contents in the copied object.
>
> How should i do this?
>
> Here is my first stab at a solution, but its not working.
> Its the dynamic downcast from Base* to SubA* that fails when i run. I
> want to use a dynamic cast since i sometimes need to do a runtime check
> to see if an object is if a certain type. I need to do a downcast to be
> able to check the values of the original (source) object.
>
> So how can i have access to the source object, use it as the downcasted
> subtype ,and restrict that access to be read-only.
>
>
> class Base
> {
> public:
> Base() : sourceObj(NULL) {}
> virtual ~Base() {}
>
> Base(const Base& other)
> {
> *this = other
> }
> Base& operator=(const Base& other)
> {
> sourceObj = &other;
> return *this;
> }
>
> protected:
> const Base* sourceObj;
>
> }

This doesn't work. The problem is called 'slicing' or 'truncation' (see FAQ
at parashift.com) and typically arises when you are trying to mix entity
behaviour (i.e. virtual interface with different implementations in derived
classes) and value semantics (objects are freely assignable and copyable).
The main problem is that you can assign 'aBase = aDerived' but this will
only copy some data and none of the behaviour.

If you want to mix these two, you need a kind of handle that knows how to
copy objects, best implemented when all objects know how to make a copy of
themselves (name copy-constructor idiom, clone-method). This handle will
replace the base how you currently use it. Still, you don't get real
assignability except by using destroy and copy in the back. Using smart
pointers helps implementing that, too, btw.

> // Line below casts an error when run in MS VC++ .NET
> SubA* a = dynamic_cast<SubA*>(sourceObj);
> if (a->anAttribute = 1)
> {
> // do something
> }

Your code is wrong/bad here. In general, when using dynamic_cast on
pointers, you should write it like this:
if( Derived* pd = dynamic_cast<Derived*>(pb))
... // derived
else
... // not derived
i.e. check the returnvalue. When using references you can omit that since
then it throws a bad_cast in case of failure.


> class SubA : Base
> {...};
> Base* aBase = new SubA();

This line can't compile because Base is not a public baseclass of SubA. I
just stumbled across this after writing most of this posting, but it is a
definite showstopper.

> // Line below casts an error when run in MS VC++ .NET
> SubA* aSub = dynamic_cast<SubA*>(aBase);

IFF this really generates any kind of errror (which you neglected to quote
or describe here), it is due to your setup or above mistake. Otherwise, in
that snippet, aSub will never be null.

Uli




Re: How to access the source of a copied object by mats

mats
Mon Aug 22 05:21:30 CDT 2005

Its true that i forgot to check the return ofthe dynamic cast in my
example. I haev it in the production code.
I also forgot to write that SubA was a public subclass of Base, (also
a typing error)

I have managed to get it working now. Now i only have to figure otu how
to restrict the access to sourceObj to be read-only. So back to the
c++faq and annotations.
Thanks for pointing me in that direction.
Btw what chapter of the Faq are you refering to when you say slicing
or truncating?

PS. nunit or any other testing framework is marvelous when trying out
ideas like this.