|
If no one actually attempts to instantiate a CFoo object, then it won't complain.
If you just do:
CFoo fred;
it will.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />
Peter Weyzen<br />
Staff Engineer<br />
<A HREF="http://www.santacruznetworks.com">Santa Cruz Networks</A>
|
|
|
|
|
Actually, you can never instantiate a CFoo , since it's an abstract class.
The problem has to do with the fact that CFoo's static (factory) method was constructing a derived class which caused the linker to want to resolve CFoo::setDefault() . This is sorta hokey, but what I was doing was wrong, since the derived class's vtable has not been initialized in the base class' constructor.
/ravi
Let's put "civil" back in "civilization"
Home | Articles | Freeware | Music
ravib@ravib.com
|
|
|
|
|
It's giving an error because you're calling CFoo::setDefault() directly, and that method is not implemented. Remember the virtual only kicks in if you call the method through a pointer. You need to call plain setDefault() to get the polymorphism that I think you are expecting.
--Mike--
Ericahist | Homepage | RightClick-Encrypt | 1ClickPicGrabber
CP SearchBar v2.0.2 released
|
|
|
|
|
Actually I'm calling CFoo::setDefault() indirectly - I neglected to mention that doSomething() is actually a factory method that serves up a specialization of a CFoo , which causes CFoo 's constructor to be called, which causes a call to a method in a derived class, which is just plain wrong!
But I still think the compiler should have caught the error.
/ravi
Let's put "civil" back in "civilization"
Home | Articles | Freeware | Music
ravib@ravib.com
|
|
|
|
|
Ravi Bhavnani wrote:
which causes CFoo's constructor to be called, which causes a call to a method in a derived class
er, you aren't calling a virtual function in the CFoo ctor, are you? The vtbl isn't initialized yet so that will probably crash at runtime with a pure virtual function call.
--Mike--
Ericahist | Homepage | RightClick-Encrypt | 1ClickPicGrabber
CP SearchBar v2.0.2 released
|
|
|
|
|
Quite right, Mike. VC6 catches that link time, presumably because the vtable entry for setDefault() is NULL.
/ravi
Let's put "civil" back in "civilization"
Home | Articles | Freeware | Music
ravib@ravib.com
|
|
|
|
|
Michael is right (almost) - you don't have "virtuality" in the constructor. Your doSomething should Create the object, and then call setDefault explicitely.
(almost: IIRC the VTable is initialized to the one ofthe base class, and you have a virtual call not only through a pointer but also in all member functions and the destructor)
"Vierteile den, der sie Hure schimpft mit einem türkischen Säbel."
sighist | Agile Programming | doxygen
|
|
|
|
|
peterchen wrote:
Your doSomething should Create the object, and then call setDefault explicitely.
Yes, that's exactly the tack I took. Thanks for your reply!
/ravi
Let's put "civil" back in "civilization"
Home | Articles | Freeware | Music
ravib@ravib.com
|
|
|
|
|
While writing some code for a class, wich also contains oveloads for the assignment operator ( = ), VC++ keeps giving C2801 errors. According to MSDN, C2801 means that assignment, class member access, subscripting or function call operators must be a non-static class member.
This is my code:
class Foo<br />
{<br />
private:<br />
CString m_String;<br />
public:<br />
Foo();<br />
Foo(CString);<br />
~Foo();<br />
friend Foo& operator= (const class Bar);<br />
}<br />
<br />
Foo::Foo (CString string)<br />
{<br />
m_String = string;<br />
}<br />
<br />
Foo& operator= (const class Bar BarInstance)<br />
{<br />
return Foo (BarInstance.m_String);<br />
}<br />
<br />
class Bar<br />
{<br />
private:<br />
CString m_String;<br />
public:<br />
Bar();<br />
~Bar();<br />
}
But that's not the whole story; the code
char* yourName = "DaFrawg";<br />
MessageBox("Hello there, %s", yourName);
will generate a messagebox with the prompt "Hello there, %s" and the caption "DaFrawg". What I want is, of course, to have the message "Hello there, DaFrawg" displayed.
Can somebody help me, please?
//Please don't mind my bad English
|
|
|
|
|
DaFrawg wrote:
But that's not the whole story; the code
char* yourName = "DaFrawg";
MessageBox("Hello there, %s", yourName);
will generate a messagebox with the prompt "Hello there, %s" and the caption "DaFrawg". What I want is, of course, to have the message "Hello there, DaFrawg" displayed.
Can somebody help me, please?
CString strMessage;<br />
<br />
strMessage.Format("Hello there, %s", yourName);<br />
MessageBox(strMessage);
Michael
'Logic, my dear Zoe, merely enables one to be wrong with authority.' - The Doctor: The Wheel in Space
|
|
|
|
|
Then why doesn't TRACE1("Hello %s", name) fail?
---QUOTE---
"ERROR: Keyboard not present - Press F1 to continue" - Most BOIS chips
|
|
|
|
|
|
Thanks, it works really good.
|
|
|
|
|
Try this:
class Bar
{
public:
Bar();
~Bar();
CString m_String;
};
class Foo
{
private:
CString m_String;
public:
Foo();
Foo(CString);
~Foo();
const Foo& operator=( const Bar& bar );
};
Foo::Foo (CString string)
{
m_String = string;
}
const Foo& Foo::operator=(const Bar& BarInstance)
{
m_String = BarInstance.m_String;
return (*this);
}
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
It still doesn't work. I now have the real code I use:
<br />
class Foo<br />
{<br />
public:<br />
Foo();<br />
virtual ~Foo();<br />
private:<br />
CString m_String;<br />
public:<br />
friend const Foo& operator= (const class Bar& BarInst);
};<br />
<br />
class Bar<br />
{<br />
public:<br />
Bar();<br />
virtual ~Bar();<br />
private:<br />
CString m_String;<br />
};<br />
<br />
const Foo& operator=(const class Bar& BarInst)
{<br />
m_String = Bar.m_String;
return (this*);
}<br />
The compiler is getting berzerk. Not only a C2801, but also two C2673 (Global functions do not have 'this' pointers), C2227 (left of m_String must point to class/struct/union), C2248 (but that's not a real problem) and C2059 (Syntax error: ';').
|
|
|
|
|
Please refer to M. Dimmick's reply. Friend functions are not considered class members; they are normal external functions that are given special access privileges. Also, friend s are not in the class’s scope, and they are not called using the member-selection operators (. and –>). The code snippet that I provided you is correct. If it is not the correct solution to your problem, however, then you must reconsider the design.
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
It's not weird at all, it's standard: operator= must be implemented as a member function, according to the definition of the language.
The error message also tells you that any overloads of operator-> , operator[] or operator() must also be implemented as a member function. I believe it also applies to compound assignments, such as += , /= , etc.
operator= must be a function that modifies the object to which it's applied, i.e. the left-hand side of the assignment statement, which is pointed to by this inside the function body. It should return a reference to the object that was modified.
|
|
|
|
|
1) the operator function IS a member of the class
2) my (new) code IS using the this pointer and returns it
And still VC++ keeps saying "Operator '=' must be an <unknown> member.
|
|
|
|
|
Hello, everyone.
I am making a program with plug-ins. So I designed SDK (header files + lib file). This sdk is being used by the main program and plug-ins. I am working VC6. Now to the problem. I want to have a global object, which can be used and modified by the main program and all plug-ins (so it is a global object in the sdk). I am confused about how this object is used by main program and dll's. It looks like main program has its own version and each dll has its own version, while I want it to be shared. How do I do it?
And another concern: for right now my sdk is a static linked library, but can I make it to be a dll too? My confustion is that program must load dll and import its functions (like plug-ins), while I want a case, when implimentation of the sdk functions are in the shared dll. I would like to have more information about this topic, does anyone know a good reading material on the subject?
Thank you.
Regards,
Alexander.
|
|
|
|
|
For DLLs:
First, every class or independent function, or variable should be exported:
see __declspec(dllexport) and __declspec(dllimport)
Second, header for objects that are exported should be included into your exe. Look into using "interfaces". Interfaces help make it possible to upgrade the DLL without relinking the EXE.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />
Peter Weyzen<br />
Staff Engineer<br />
<A HREF="http://www.santacruznetworks.com">Santa Cruz Networks</A>
|
|
|
|
|
Could you be more specific about "interfaces" for me it looks more like a COM termenology.
Regards,
Alexander.
|
|
|
|
|
COM does use interfaces.
Each object basically has 2 class descriptors.
class __declspec(dllexport) CFredInterface
{
virtual void DoSomething() = 0;
};
class __declspec(dllexport) CFred : public CFredInterface
{
// variable definitions
// other method definitions
// and...
virtual void DoSomething() {}
};
CFredInterface __declspec(dllexport) *FredFactory()
{
return new CFred();
}
The interfaces let you publish only the parts of the classes that you want to other people. You only give out the headers to the interfaces, which defines how people interact with your objects, and doesn't make you share everything with the people that use your code.
The FredFactory gives you a way to instantiate a CFredInterface based class. The user only thinks they are getting a CFredInterface class, they don't need to what they are really getting (CFred).
You should read up on this stuff in "Design Patterns" -- a very important book for most OOP concepts. See: Amazon: http://www.amazon.com/exec/obidos/tg/detail/-/0201633612/002-6725511-1144041?v=glance[^]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />
Peter Weyzen<br />
Staff Engineer<br />
<A HREF="http://www.santacruznetworks.com">Santa Cruz Networks</A>
|
|
|
|
|
__declspec(dllexport) does not answer the problem of shared objects.
Regards,
Alexander.
|
|
|
|
|
When you refer to "shared", what exactly do you mean?
It could mean that the DLL lives as only one instance among many programs. This would mean that data in the DLL is shared among all...
It could mean that code lives in a DLL, and is used by each program independently... Each program has it's own copy of DLL data loaded.
Please define what you mean by shared.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />
Peter Weyzen<br />
Staff Engineer<br />
<A HREF="http://www.santacruznetworks.com">Santa Cruz Networks</A>
|
|
|
|
|
By shared I mean the same object is used by all dlls, so it is your first statement. I want all the programms to modify the same object. But right now I have a library (not dll), let's call it sdk.lib which has definition of the global object. My main program is linked with this library (so it has access to the global object). Then I have a dll, which is also linked with the sdk.lib. The question is what is the way to have main program and dll use the same global object defined in sdk.lib (not to have different instances, but to refer to the same one). Maybe I can not do it with a statically linked library sdk.lib?
In general, I want to have an sdk (like Photoshop SDK for example), so people could design their own plug-ins to be used in my program. And I am trying to understand the proper way to set-up my vc projects.
Regards,
Alexander.
|
|
|
|