BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

operator * overide in BDS2006

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (Language C++)
View previous topic :: View next topic  
Author Message
Mark Erickson
Guest





PostPosted: Sun Dec 10, 2006 5:00 am    Post subject: operator * overide in BDS2006 Reply with quote



Hi,

I'm trying to get Turbo Powers ShellShock components to work in BDS2006
C++Builder. The following line - from a header that is generated by BDS
when installing the components - causes a compiler error:

operator IDropTarget*(void) { return (IDropTarget*)&__IDropTarget; }

The error message is:

[C++ Error] StShlCtl.hpp(458): E2076 Overloadable operator expected

In the help for the error it says that certain operators cannot be
overloaded:

the field-selection dot (.)
dot-star (.*)
double colon (:Smile
conditional expression (?Smile

In the help on Operator Overloading it says that the * (Pointer
dereference) is legal overload. I *think* the statement above is an
operator * overload?

The same statement compiles without error in BCB6.

Does anyone have any ideas?

Here's a little more code that may help

// C++ auto-generated

class PASCALIMPLEMENTATION TStCustomShellTreeView : public
Comctrls::TCustomTreeView
{
typedef Comctrls::TCustomTreeView inherited;

protected:
// Snip lots of that I don't *think* is relevant.

private:
void *__IDropTarget; /* IDropTarget [DragOver=StDragOver] */

public:
operator IDropTarget*(void) { return (IDropTarget*)&__IDropTarget; };

// Delphi original code

TStCustomShellTreeView = class(TCustomTreeView, IDropTarget)
protected { private }
// Snip lots of that I don't *think* is relevant.

{ IDropTarget declarations }
function DragEnter(const dataObj : IDataObject; grfKeyState :
Longint;
pt : TPoint; var dwEffect : Longint): HResult; stdcall;
function IDropTarget.DragOver = StDragOver;
function StDragOver(grfKeyState : Longint; pt : TPoint;
var dwEffect : Longint): HResult; stdcall;
function DragLeave : HResult; stdcall;
function Drop(const dataObj : IDataObject; grfKeyState : Longint;
pt : TPoint;
var dwEffect : Longint): HResult; stdcall;

// Snip lots of that I don't *think* is relevant.
end;

The IDropTarget is an interface I believe which I've never used myself.

Thanks
Mark

--
Back to top
Mark Erickson
Guest





PostPosted: Sun Dec 10, 2006 9:10 am    Post subject: Re: operator * overide in BDS2006 Reply with quote



Hi, Ok, so what's the problem then? Why's the compiler complaining
about it? After all BDS generated it Wink. It's the error message that's
caused me to think it's an operator * overload. I'm not used to
interfaces either so I'm getting nowhere fast with this. The thing
that's really getting me is exactly the same code compiles fine in BCB6.

Any ideas on how to fix it? I've been trying to get further with it all
night but I'm at exactly the same point I was when I posted the
original post! Confused!

Thanks
Mark

--



Remy Lebeau (TeamB) wrote:

Quote:

"Mark Erickson" <mark (AT) merickson (DOT) demon.co.uk> wrote in message
news:xn0eusbqtch8in000 (AT) forums (DOT) borland.com...

I think the statement above is an operator * overload?

It is not overiding the '*' operator at all. It is declaring a new
user-defined operator that returns an IDropTarget pointer. That has
nothing to do with the '*' operator.


Gambit
Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Sun Dec 10, 2006 9:10 am    Post subject: Re: operator * overide in BDS2006 Reply with quote



"Mark Erickson" <mark (AT) merickson (DOT) demon.co.uk> wrote in message
news:xn0eusnih1aa00000 (AT) forums (DOT) borland.com...

Quote:
Hi, Ok, so what's the problem then? Why's the compiler
complaining about it? After all BDS generated it Wink

Actually, the Pascal compiler generated it. That doesn't mean the C++
compiler has to always like what Pascal produces, which obviously is the
case in this situation.

What strikes me as odd is that the BCB 6 compiler introduced native support
for VCL classes that use multiple inheritance to derive directly from
interfaces. So I wonder why Borland hasn't updated the Pascal compiler yet
to stop producing such outdated code altogether. In this case, it would
make more sense to derive from IDropTarget instead of implmenting it as a
data member, ie:

class PASCALIMPLEMENTATION TStCustomShellTreeView : public
Comctrls::TCustomTreeView, public IDropTarget
{
//...
};

Quote:
It's the error message that's caused me to think it's an operator *
overload.


Like I said, it has nothing to do with the * operator. Do not be confused
by the fact that there is an * in the signature. The * is tied to the
IDropTarget portion, declaring it as a pointer. The actual * operator is
something completely different.

Quote:
The thing that's really getting me is exactly the same code compiles fine
in BCB6.


BDS uses a newer compiler. Obviously, Borland broke something along the
way.

Quote:
Any ideas on how to fix it?

Do you have all of the BDS patches installed?


Gambit
Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Sun Dec 10, 2006 9:10 am    Post subject: Re: operator * overide in BDS2006 Reply with quote

"Mark Erickson" <mark (AT) merickson (DOT) demon.co.uk> wrote in message
news:xn0eusbqtch8in000 (AT) forums (DOT) borland.com...

Quote:
I *think* the statement above is an operator * overload?

It is not overiding the '*' operator at all. It is declaring a new
user-defined operator that returns an IDropTarget pointer. That has nothing
to do with the '*' operator.


Gambit
Back to top
Mark Erickson
Guest





PostPosted: Sun Dec 10, 2006 3:31 pm    Post subject: Re: operator * overide in BDS2006 Reply with quote

Yes update 2 and hotfixes 1 and 3 to 6. I skipped 2 as I don't use
CaliberRM. (not even sure what it's for to be honest).

I suppose editing the header to inherit as you suggest would be daft
considering the remark at the top of the file says not to do it. Are
these headers re-created every time you build an app or just when you
build the components? If the latter then is there any other reason not
to edit the header directly?

I've started to have a go at TP's Async Pro now and am getting equally
weird errors. Why did they sell up! grr!

I need some kip!

Thanks
Mark

--



Remy Lebeau (TeamB) wrote:

Quote:

"Mark Erickson" <mark (AT) merickson (DOT) demon.co.uk> wrote in message
news:xn0eusnih1aa00000 (AT) forums (DOT) borland.com...

[snip]

Do you have all of the BDS patches installed?


Gambit
Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Mon Dec 11, 2006 4:43 am    Post subject: Re: operator * overide in BDS2006 Reply with quote

"Mark Erickson" <mark (AT) merickson (DOT) demon.co.uk> wrote in message
news:xn0eussb37slah001 (AT) forums (DOT) borland.com...

Quote:
Are these headers re-created every time you build an app or just
when you build the components?

Just when compiling the original Pascal code.


Gambit
Back to top
Jean-Marie Babet
Guest





PostPosted: Wed Dec 13, 2006 1:05 am    Post subject: Re: operator * overide in BDS2006 Reply with quote

Hello,

Quote:
What strikes me as odd is that the BCB 6 compiler introduced native
support
for VCL classes that use multiple inheritance to derive directly from
interfaces. So I wonder why Borland hasn't updated the Pascal compiler yet
to stop producing such outdated code altogether. In this case, it would
make more sense to derive from IDropTarget instead of implmenting it as a
data member, ie:

Well, because there's a subtlety in the way C++ and Delphi work. In Delphi
the methods of an interface you inherit from can be implemented by the base
class you derive from. Given IBase, IDerived and TBase and TDerived:

IBase {};
TBase : IBase {...}; // TBase implements IBase

IDerived: IBase {...};
TDerived: TBase, IDerived {...};

In Delphi (and other languages where interfaces are native), TDerived has to
implement just the methods unique to IDerived; the methods of IBase are
inherited from TBase. However, that's not the case in C++: TDerived has to
implement methods of IBase even though all it will probably do is to
delegate to TBase::methodName. Interfaces are not any different from any
other class in C++ and the rules of multiple inheritance dictate that a
class implements all pure virtual methods of its base types, lest it be an
abstract type. Anyone who has used TInterfacedObject in C++ finds out that
QI/AddRef/Release cannot be left out as in Delphi. Or when the wizard
generates SOAP or XMLDataBinding classes, you've noticed these macros (see
XMLNodeImp.h) that basically delegate all methods of the base interface.

At some point, we did switch DCC32 to emit interfaces as inherited but that
made a lot of classes abstract from a C++ point of view. Emitting inline
versions of all interface methods inherited from some base type in the
hierarchy required major rework of .HPP emission. After chatting with the
compiler person about this issue, we opted to keep the current model -
although, if time allows, I plan to switch the interface conversion operator
generated in .hpp files to go through TObject::GetInterface to ensure
reference counting is done properly.

Cheers,

Bruneau.
Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Wed Dec 13, 2006 2:49 am    Post subject: Re: operator * overide in BDS2006 Reply with quote

"Jean-Marie Babet" <bbabet (AT) borland (DOT) com> wrote in message
news:457efc75$1 (AT) newsgroups (DOT) borland.com...

Quote:
In Delphi (and other languages where interfaces are native), TDerived
has to implement just the methods unique to IDerived; the methods of
IBase are inherited from TBase. However, that's not the case in C++

It is if you use virtual inheritance.

Quote:
TDerived has to implement methods of IBase even though all it will
probably do is to delegate to TBase::methodName.

In your example, if I use virtual inheritance for IBase, the following
works:

#include <stdio.h>

class IBase
{
public:
virtual void OutputMsg1() = 0;
virtual void OutputMsg2() = 0;
};

class TBase : virtual public IBase
{
public:
TBase()
{
printf("%s\n", __FUNC__);
}

virtual ~TBase()
{
printf("%s\n", __FUNC__);
}

virtual void OutputMsg1()
{
printf("%s\n", __FUNC__);
}
};

class IDerived : virtual public IBase
{
public:
virtual void OutputMsg3() = 0;
};

class TDerived : public TBase, public IDerived
{
public:
TDerived()
: TBase()
{
printf("%s\n", __FUNC__);
}

virtual ~TDerived()
{
printf("%s\n", __FUNC__);
}

virtual void OutputMsg2()
{
printf("%s\n", __FUNC__);
}

virtual void OutputMsg3()
{
printf("%s\n", __FUNC__);
}
};

int main(int argc, char* argv[])
{
TDerived d;
IBase *pb = &d;
pb->OutputMsg1();
pb->OutputMsg2();
d.OutputMsg3();
return 0;
}

I get the following output:

TBase::TBase
TDerived::TDerived
TBase::OutputMsg1 <-- inherited
TDerived::OutputMsg2
TDerived::OutputMsg3

Quote:
Anyone who has used TInterfacedObject in C++ finds out that
QI/AddRef/Release cannot be left out as in Delphi.

That is because those specific methods in particular are mapped differently
in C++ than in Delphi. But that does not apply to interfaces in general.
The only reason to implement all of the interface methods in the derived
class is when there are multiple vtable entries for duplicate interfaces (in
this case, IBase is coming from both TBase and IDerived when not using
virtual inheritance, so both have to be implemented separately). But
virtual inheritance merges the duplicates together. Then you can implement
the methods in a base class and inherit them in a derived class.

Quote:
At some point, we did switch DCC32 to emit interfaces as inherited
but that made a lot of classes abstract from a C++ point of view.

Borland was probably trying to use public inheritance for the interfaces.
Try using virtual inheritance instance.

Quote:
Emitting inline versions of all interface methods inherited from some base
type in the hierarchy required major rework of .HPP emission. After
chatting with the compiler person about this issue, we opted to keep the
.. current model - although, if time allows, I plan to switch the interface

conversion
Quote:
operator generated in .hpp files to go through TObject::GetInterface to
ensure reference counting is done properly.

That will have subtle effects on existing code that relies on the reference
count not being incremented by the operator.


Gambit
Back to top
Jean-Marie Babet
Guest





PostPosted: Wed Dec 13, 2006 7:17 am    Post subject: Re: operator * overide in BDS2006 Reply with quote

Quote:
In Delphi (and other languages where interfaces are native), TDerived
has to implement just the methods unique to IDerived; the methods of
IBase are inherited from TBase. However, that's not the case in C++

It is if you use virtual inheritance.

Yes, virtual inheritance is good C++ solution to the generic interface
problem but it cannot be used to expose classes with interfaces that are
implemented in Delphi to the C++ side: the binary layout of a class with a
virtual base is different from when the base is not virtual. Virtual
inheritance implies a 'virtual base class table' pointer within the vtable;
virtual inheritance also triggers C++ to pass a hidden parameter at
construction (to suppress base class construction). By using 'virtual'
inheritance you'll come closer to the semantics of Delphi interface but it
will crash at runtime because of the layout and protocol of C++ virtual
inheritance is incompatible with what the Delphi side implements and expects
when called.


Quote:
That will have subtle effects on existing code that relies on the
reference
count not being incremented by the operator.

Well, there are bugs filed currently against these operators because they
don't properly handle ref. counting. I'll see if I can emit both the old and
new style operators conditionalized via a macro.

Cheers,

Bruneau.
Back to top
Guest






PostPosted: Fri Jan 12, 2007 5:33 pm    Post subject: Re: operator * overide in BDS2006 Reply with quote

Mark Erickson schrieb:

Quote:
Hi,

I'm trying to get Turbo Powers ShellShock components to work in BDS2006
C++Builder. The following line - from a header that is generated by BDS
when installing the components - causes a compiler error:

operator IDropTarget*(void) { return (IDropTarget*)&__IDropTarget; }

The error message is:

[C++ Error] StShlCtl.hpp(458): E2076 Overloadable operator expected

In the help for the error it says that certain operators cannot be
overloaded:

the field-selection dot (.)
dot-star (.*)
double colon (:Smile
conditional expression (?:)

In the help on Operator Overloading it says that the * (Pointer
dereference) is legal overload. I *think* the statement above is an
operator * overload?

The same statement compiles without error in BCB6.

Does anyone have any ideas?

Here's a little more code that may help

// C++ auto-generated

class PASCALIMPLEMENTATION TStCustomShellTreeView : public
Comctrls::TCustomTreeView
{
typedef Comctrls::TCustomTreeView inherited;

protected:
// Snip lots of that I don't *think* is relevant.

private:
void *__IDropTarget; /* IDropTarget [DragOver=StDragOver] */

public:
operator IDropTarget*(void) { return (IDropTarget*)&__IDropTarget; };

// Delphi original code

TStCustomShellTreeView = class(TCustomTreeView, IDropTarget)
protected { private }
// Snip lots of that I don't *think* is relevant.

{ IDropTarget declarations }
function DragEnter(const dataObj : IDataObject; grfKeyState :
Longint;
pt : TPoint; var dwEffect : Longint): HResult; stdcall;
function IDropTarget.DragOver = StDragOver;
function StDragOver(grfKeyState : Longint; pt : TPoint;
var dwEffect : Longint): HResult; stdcall;
function DragLeave : HResult; stdcall;
function Drop(const dataObj : IDataObject; grfKeyState : Longint;
pt : TPoint;
var dwEffect : Longint): HResult; stdcall;

// Snip lots of that I don't *think* is relevant.
end;

The IDropTarget is an interface I believe which I've never used myself.

Thanks
Mark

--Hello Mark,
I have the same problem. ShellShock runs under C++Builder4, but not in

C++Builder 5. Did You get any information about the problem?

Thanks
Norbert
Back to top
Thomas Maeder [TeamB]
Guest





PostPosted: Fri Jan 12, 2007 10:31 pm    Post subject: Re: operator * overide in BDS2006 Reply with quote

Please direct your browser at http://info.borland.com/newsgroups/ and
read the newsgroup guidelines. One of them asks us not to quote entire
posts we are following up to; instead, please trim the quotes to the
parts relevant for your reply. Thanks!
Back to top
Vaclav Cechura
Guest





PostPosted: Fri Jan 19, 2007 7:27 pm    Post subject: Re: operator * overide in BDS2006 Reply with quote

Alan Bellingham <alan (AT) lspace (DOT) org> wrote:
Quote:
You've gone off down the wrong path, due to a confusion over C++ syntax.
The syntax is wrong. The word "operator" should immediately
precede the name of the operator.


It does. This is a standard user-defined conversion function (see 12.3,
especially 12.3.2), and as such, the name of the method is 'operator
IDropTarget*()', and the type of the return value is therefore
'IDropTarget*' (*not* included in the declaration because it would be
redundant).

What to say now. You're right, I must have been temporarily
blind.

Quote:
expression "return (IDropTarget*)&__IDropTarget;" is wrong
as it tries to return the addres of a class member...

This return is correct for the code written.

Suddenly, I got it: it converts TStCustomShellTreeView to
IDropTarget pointer...

I will think twice before posting in the future. I promise.
Back to top
Vaclav Cechura
Guest





PostPosted: Fri Jan 19, 2007 7:29 pm    Post subject: Re: operator * overide in BDS2006 Reply with quote

"Vaclav Cechura" <no (AT) spam (DOT) please> wrote:
Quote:
Suddenly, I got it: it converts TStCustomShellTreeView to
IDropTarget pointer...

I will think twice before posting in the future. I promise.


May the subject of the post: "operator * overide in BDS2006"
be my excuse.
Back to top
Alan Bellingham
Guest





PostPosted: Fri Jan 19, 2007 7:56 pm    Post subject: Re: operator * overide in BDS2006 Reply with quote

"Vaclav Cechura" <n (AT) s (DOT) p> wrote:

Quote:
May the subject of the post: "operator * overide in BDS2006"
be my excuse.

Ah, I will have to admit that I rarely notice subjects this far down a
thread.

Alan Bellingham
--
10th Anniversary ACCU Conference: 11-14 April 2007 - Oxford, UK
(Booking now open: see http://accu.org/index.php/conferences for details)
Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (Language C++) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.