How can I achieve this behaviour?

J

JKop

class Cow
{
public:

void EatGrass() const {}
};

class Brow
{
private:

Cow cow;

public:

operator Cow&()
{
return cow;
}
};

int main()
{
Brow k;

k.EatGrass();
}


Is there any way I can achieve the above, whereby a Brow is implicitly
converted to a Cow? Here would be another example:

class Blah
{
private:

double a;

public:

operator double&()
{
return a;
}
};


int main()
{
Blah jk;

jk = 52.0;
}


-JKop
 
J

Jonathan Turkanis

JKop said:
class Cow
{
public:

void EatGrass() const {}
};

class Brow
{
private:

Cow cow;

public:

operator Cow&()
{
return cow;
}
};

int main()
{
Brow k;

k.EatGrass();
}


Is there any way I can achieve the above, whereby a Brow is implicitly
converted to a Cow?

Yes:

class Brow
{
private:

Cow cow;

public:

Cow& operator. ()
{
return cow;
}
};

:)

Seriously .. this is a reasona to prefer non-member functions to member
functions.

class Brow
{
private:

Cow cow;

public:

operator Cow&()
{
return cow;
}

operator const Cow&() const
{
return cow;
}
};

void EatGrass(const Cow&);

Jonathan
 
J

JKop

Jonathan Turkanis posted:
Yes:

class Brow
{
private:

Cow cow;

public:

Cow& operator. ()
{
return cow;
}
};

:)

By golly I love it!

So now we can do the following:

void SomeFunc(Cow& k);

int main()
{
Brow t;

SomeFunc(t); //operator Cow&
}

Plus we can access it's members:

int main()
{
Brow t;

t.EatGrass();
}

The only thing left is to access its operators:

int main()
{
Brow t;

t = 6;

//Assuming Cow has an assignment operator
}

Is there any easy way to do this, other than rhyming them all off:

class Brow
{
private:

Cow f;

public:

operator==(const Cow& r)
{
return f == r;
}

operator*(const Cow& r)
{
return f * r;
}
};

Templates would be required to get in all the operators and variable
argument types.


-JKop
 
I

Ioannis Vranos

Jonathan said:
Yes:

class Brow
{
private:

Cow cow;

public:

Cow& operator. ()
{
return cow;
}
};

:)

Seriously .. this is a reasona to prefer non-member functions to member
functions.

class Brow
{
private:

Cow cow;

public:

operator Cow&()
{
return cow;
}

operator const Cow&() const
{
return cow;
}
};

void EatGrass(const Cow&);



However constructors should be preferred when another class has to be
made compatible with the current class, and operator types() when our
current class has to become compatible with another class, of which we
have no access to its definition.






Regards,

Ioannis Vranos

http://www23.brinkster.com/noicys
 
J

Jonathan Turkanis

Ioannis Vranos said:
However constructors should be preferred when another class has to be
made compatible with the current class, and operator types() when our
current class has to become compatible with another class, of which we
have no access to its definition.

I was thinking of Cow as the class to which we didn't have access. We can still
define Brow as above, and

void EatGrass(const Cow& cow) { cow.EatGrass(); }

Jonathan
 
J

Jonathan Turkanis

Ioannis Vranos said:
Yes you can't. But I think the first one he provided was a joke.

Right. Maybe I should have used a different smiley: :-D ???

Jonathan
 
P

PKH

JKop said:
class Cow
{
public:

void EatGrass() const {}
};

class Brow
{
private:

Cow cow;

public:

operator Cow&()
{
return cow;
}
};

int main()
{
Brow k;

k.EatGrass();
}


Is there any way I can achieve the above, whereby a Brow is implicitly
converted to a Cow? Here would be another example:

class Blah
{
private:

double a;

public:

operator double&()
{
return a;
}
};


int main()
{
Blah jk;

jk = 52.0;
}


-JKop

You could also use a ClassID approach like this :
( a bit more code than the other suggestions, but quite powerful)

typedef char ClassID;

class CClassIDBase
{
public:
static ClassID
m_cClassID;

virtual CClassIDBase* RequestClass(const ClassID& c)
{
return (&c == &m_cClassID) ? this : NULL;
}
};


class CCow : public CClassIDBase
{
public:
static ClassID
m_cClassID;

public:
void EatGrass(){}
virtual CClassIDBase* RequestClass(const ClassID& c)
{
return (&c == &m_cClassID) ? this : CClassIDBase::RequestClass(c);
}
};


class CBrow : CClassIDBase
{
public:
static ClassID
m_cClassID;

CCow
m_cCow;

public:
virtual CClassIDBase* RequestClass(const ClassID& c)
{
if (&c == &CCow::m_cClassID)
{
return &m_cCow;
}
else
{
return (&c == &m_cClassID) ? this : CClassIDBase::RequestClass(c);
}
}
};


ClassID
CClassIDBase::m_cClassID = 0,
CCow::m_cClassID = 0,
CBrow::m_cClassID = 0;


int main(int argc, char* argv[])
{
CCow
*pcCow;

CBrow
cBrow;

if ((pcCow = (CCow*)cBrow.RequestClass(CCow::m_cClassID)) != NULL)
{
pcCow->EatGrass();
}

return 0;
}
 
A

Alf P. Steinbach

* JKop:
class Cow
{
public:

void EatGrass() const {}
};

class Brow
{
private:

Cow cow;

public:

operator Cow&()
{
return cow;
}
};

int main()
{
Brow k;

k.EatGrass();
}


Is there any way I can achieve the above, whereby a Brow is implicitly
converted to a Cow?

Very simple, derive Brow from Cow:

class Brow: public Cow
{
};


Here would be another example:

class Blah
{
private:

double a;

public:

operator double&()
{
return a;
}
};


int main()
{
Blah jk;

jk = 52.0;
}

Give class Blah an assignment operator (which implies also a copy
constructor) and perhaps also a conversion to double,

class Blah
{
public:
Blah( Blah const& another ) { ... }
Blah( double number ) { ... }

Blah& operator=( double number )
{
...
return *this;
}

operator double() const
{
return ...;
}
};

What you cannot do (except by providing access to Blah internals)
is to have assignments to something of 'double' type affect a Blah.
 
A

Alf P. Steinbach

* JKop:
Alf P. Steinbach posted:


I can't do this. At the moment I'm writing a class for a
re-seatable reference.

As I recall there have been discussions of allowing operator.()
or something similar to be defined per class, but it's no help
to you now.

If the definition of "reference" is to be able to use "." then
sorry, no can do in the general case.

The language does not support that.
 
G

Gary Labowitz

Jonathan Turkanis said:
I was thinking of Cow as the class to which we didn't have access. We can still
define Brow as above, and

void EatGrass(const Cow& cow) { cow.EatGrass(); }

Maybe I'm just missing the joke, but how can the code that invokes EatGrass
pass in a reference to a Cow object that it doesn't have access to? Whatever
code calls EatGrass must have ownership of a Cow object to pass. So how does
it get one? In any case, it won't be the Cow object in a Brow object, since
that is hidden. Are you just goofing around?
 
I

Ioannis Vranos

Alf said:
As I recall there have been discussions of allowing operator.()
or something similar to be defined per class, but it's no help
to you now.

If the definition of "reference" is to be able to use "." then
sorry, no can do in the general case.

The language does not support that.


operator.() overloading is not supported, because there is no reason to
support that. operator->() is supported though, in case you want the
objects to behave like pointers.






Regards,

Ioannis Vranos

http://www23.brinkster.com/noicys
 
A

Alf P. Steinbach

* Ioannis Vranos:
operator.() overloading is not supported, because there is no reason to
support that.

That opinion is interesting.

operator->() is supported though, in case you want the objects
to behave like pointers.

I don't think JKop is unaware of that, or of the many other possibilities
were he to drop the main requirement & reason for existence of his class.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,525
Members
44,997
Latest member
mileyka

Latest Threads

Top