|
Hi !
I was trying to implement a 'Rational Numbers' class when I came across something strange that I never noticed before and that I cannot explain.
Here is my class :
class CRational
{
private:
long m_lNumerator;
long m_lDenominator;
public:
CRational(long lNum=0, long lDenom=1)
{
m_lNumerator=lNum;
m_lDenominator=lDenom;
};
CRational(const CRational& objNombre)
{
m_lNumerator=objNombre.m_lNumerator;
m_lDenominator=objNombre.m_lDenominator;
};
CRational& operator=(const CRational& objNombre)
{
m_lNumerator=objNombre.m_lNumerator;
m_lDenominator=objNombre.m_lDenominator;
return *this;
};
long GetNumerator() { return m_lNumerator; };
long GetDenominator() { return m_lDenominator; };
};
This class is working fine, but I'm wondering why, in the copy constructor, these lines :
m_lNumerator=objNombre.m_lNumerator;
m_lDenominator=objNombre.m_lDenominator;
are allowed by the compiler, because I'm accessing private members of an object.
Well, I tried anyway to change the copy constructor to this :
CRational& operator=(const CRational& objNombre)
{
m_lNumerator=objNombre.GetNumerator();
m_lDenominator=objNombre.GetDenominator();
return *this;
};
...which is refused by the compiler :
error C2662: 'GetNumerator' : cannot convert 'this' pointer from 'const class CRational' to 'class CRational &'
It compiles fine if I remove the 'const' in the declaration of the constructor, which seems strange to me, because I'm not modifying the object 'objNombre', just using its accessors....
Anyone could explain me what's going on ??
Thanks !
Jerome
|
|
|
|
|
Jerome Conus wrote:
This class is working fine, but I'm wondering why, in the copy constructor, these lines :
m_lNumerator=objNombre.m_lNumerator; m_lDenominator=objNombre.m_lDenominator;
are allowed by the compiler, because I'm accessing private members of an object.
This is standard C++... As for the second question, I did not understand what changed from the original code to the example you show. They do look the same... Do you mean copy constructor or assignement operator?
|
|
|
|
|
Thanks for answering my first question.
For my second question, there is a difference :
In the original code, I'm directly accessing the member variables or the class, in the seconde version, I use an accessor, ie instead of doing MyRationalObject.m_lNumerator, I use the accessor : MyRationalObject.GetNumerator() .
The problem is that in the second version, I cannot have the parameter as const anymore.....
Jerome
|
|
|
|
|
Mmmm... Where were my reading glasses? Try to declare the accessors as const , like const long Get... .
|
|
|
|
|
Yep, it's working now ! Thanks !
Jerome
|
|
|
|
|
Jerome,
Alvaro's reply is better than mine: it is the recommended one (const must come after the declaration). If you have problems with this kind of stuff, as I do sometimes, read "Effective C++" from Scott Meyers. It will clarify these questions an many more...
Cheers
|
|
|
|
|
eheh...where were MY reading glasses !! I thought your previous answer (telling me to use the 'const' in the accessors) was the same as the answer of Alvaro, which is the one I tried and that's why I told you it was working fine !!
Anyway, thank you for helping me !
Jerome
|
|
|
|
|
Jerome Conus wrote:
This class is working fine, but I'm wondering why, in the copy constructor, these lines are allowed by the compiler, because I'm accessing private members of an object.
Yes, but the object is of the same class as "this". So the compiler allows it.
Jerome Conus wrote:
Anyone could explain me what's going on ??
objNombre is passed as const reference. "Const" means that it can't be changed, so you can only call member functions that are also declared const. Since GetNumerator and GetDenominator are not const member functions, they could technically be used to change the object's data (member variables). But since you passed objNombre as a const, then it's not legal. I hope this makes sense.
Anyway, you have two options to solve this:
1. Make objNombre not const. This will allow you to call const and non-const members from it. However, this is not the optimal solution.
2. Add const to the declaration of GetNumerator and GetDenominator:
long GetNumerator() const { return m_lNumerator; }; <br />
long GetDenominator() const { return m_lDenominator; };
This is the proper way to do things. Anytime a member function does not change the object's data, it should be made const so that it can be called by const objects, such as your objNombre.
Regards,
Alvaro
All you need in this life is ignorance and confidence, and then success is sure. -- Mark Twain
|
|
|
|
|
Thank you for your answer, everything does make sense now !!
Thanks,
Jerome
|
|
|
|
|
hello all,
i have a little problem with remove scrollbar in htmlview.
when i load a web page, i must wait the document is complete before remove scrollbar.
i do this:
pView->Navigate2(pSite.URLPage,NULL,NULL);
pView->RemoveSlider();
and i want to do pView->RemoveSlider(); only when the page is totaly loaded.
how to wait without blocking the download and the program ???
if you need more information ask me.
Thx you in advance
|
|
|
|
|
OnDocumentComplete gets fired when a document has reached READYSTATE_COMPLETE state. But I think that, as OnNavigateComplete2 (which could also suffice your requirements) does, it's also called for frames inside a frameset.
So you'll need to detect whether it's your document that has finished loading. For that you could store the url you navigated to (in it's canonicalized form) and compare it to that given in one of the above functions. If they're equal, your download is complete.
We are men. We are different. We have only one word for soap. We do not own candles. We have never seen anything of any value in a craft shop. We do not own magazines full of photographs of celebrities with their clothes on. - Steve
|
|
|
|
|
Thx Schlaubi !
yes i know these function but my problem is to wait during the loading.
if i do :
void CBrowserMDIView::OnDocumentComplete(LPCTSTR lpszURL)
{
m_LoadingComplete = TRUE;
}
while (1)
{
if (pView->m_LoadingComplete == TRUE)
{
pView->RemvoveSlider();
.......
break;
}
}
this is a bad solution because my application freeze.During the while(1) the page is not loaded.
my problem is not really to know when a page is loaded but how to wait during the loading without freezing.
thx
|
|
|
|
|
Ok, the problem is that your while loop consumes all the computation time, thus blocking your whole application. One solution could be to place a Sleep(500) call inside your loop, choosing an appropriate sleeping time. This gives your application the possibility to go on in processing during your sleep time.
You could also place your call to RemoveSlider inside a worker thread, passing a pointer to your htmlview as parameter. And then you could work with an event, which could be set when your page is loaded, and your thread waits for this event by WaitForSingleObject.
We are men. We are different. We have only one word for soap. We do not own candles. We have never seen anything of any value in a craft shop. We do not own magazines full of photographs of celebrities with their clothes on. - Steve
|
|
|
|
|
Schlaubi wrote:
One solution could be to place a Sleep(500)
I have trying this but during the Sleep(1000) the page is not loaded it's freezing.
Schlaubi wrote:
You could also place your call to RemoveSlider inside a worker thread, passing a pointer to your htmlview as parameter. And then you could work with an event, which could be set when your page is loaded, and your thread waits for this event by WaitForSingleObject.
I hoped there is a solution without thread but if there isn't i'm trying this.
Thx !
|
|
|
|
|
now I have another problem.
so, I created main dialog window and have another window which serves like "send message" dialog in ICQ(it show's me messages received from another users), so how can I activate it dynamicaly after message receive, and don't activate if it was active, mean how to check in this situation whether my dialog is active. thanks.
|
|
|
|
|
One solution is a pointer. Check for NULL.
Kuphryn
|
|
|
|
|
Hi,
It maybe a simple problem. I download a MSVC6.0 project from the internet. Some problems ocurred when i try to compile and
debug it.
First, the project can only compiled with release version, (i cannot change the compiling mode due to=> from the settings menu, the debug and release combobox is grey). If i want to compile it with debug mode how should i do?
In addtion, when compiling the project, I got the following error:
HC5011: Error: mlva.hpj :
Cannot open the file "C:\Program Files\Microsoft Visual Studio\VC98\MFC\include\afxhelp.hm."
I have cheched the file, there is afxhelp.hm indeed. Why cannot open? Hope get your helps!
Thanks a lot!
chen
|
|
|
|
|
Could you create your own workspace, then copy/port the application from internet to your workspace and compile. This way you have more control of the project settings.
R.Bischoff | C++
.NET, Kommst du mit?
|
|
|
|
|
Hi,
The successful by re-creating the project. Thanks a lot!
|
|
|
|
|
Hello all. I have a little issue that I'm unsure of how to do. I have a bunch of dlls that are used by various applications. I have 1 application though which needs to call some functions located in ALL the dlls. My problem is how do I dynamically Load and Unload the Dlls from this application so that my app will still run if there are NO dlls present?
What do I have to do to allow this? Any help on the matter is grealy appreciated.
Thank you.
Dan Willis
|
|
|
|
|
|
Check out the LoadLibrary API. To retrieve the address of the function you need to call, use the GetProcAddress API with the handle returned by LoadLibrary .
Have fun.
|
|
|
|
|
Doh!
I knew it was simple one. 1 more question. I thought there was some linking option that I needed to turn on or off to force a dynamic load of the dlls. Is this true, or does the adding of the Load Library take care of that issue?
Once again, Thanks alot!
Dan Willis
|
|
|
|
|
You should prototype your export functions with extern "C" in order to avoid name mangling. Anyway, take a look at the DLL's link map or export list to make sure the functions do get exported with human-readable names (the ones you will have to use in GetProcAddress ).
Have more fun!
|
|
|
|
|
Even Better! Woo Hoo!
Another question to have even more fun!
How do I look at the dll link map and/or export list?
Dan Willis
|
|
|
|