|
You are right on the issue that I have crap design, but this is no means homework. I have been programming c++ for about 2 years, completely self taught, and learning by my mistakes as I go along, since I have no one to teach me and I am not doing this for a living.
I have found a workaround to this by not declaring that member private anymore.
My understanding of private is that it's a member of a class that can be accessed only by the functions of that class and/or the class object, correct?
Also, although your criticism is appreciated, and I know I am a really bad coder (should have seen me 2 years ago!!!!) a little help would be appreciated to go along with the criticism.
|
|
|
|
|
georgiek50 wrote:
a little help would be appreciated to go along with the criticism.
Point taken
What exactly are you trying to achieve? I might be able to provide more constructive guidance with a brief outline of the task you're trying to solve.
Ian Darling
"The different versions of the UN*X brand operating system are numbered in a logical sequence: 5, 6, 7, 2, 2.9, 3, 4.0, III, 4.1, V, 4.2, V.2, and 4.3" - Alan Filipski
|
|
|
|
|
I have read some of the replies and the best way to learn is by doing.
If you wish to access a private memvebers of a class from a function that is not part of the class, you need to do one of three things: Provide member functions in your class to access the private member variables (preferded method), declare your function(s) as a friend of the class (this says the function knows what it is doing), or make the member data public (this is normaly a bad idea).
I recommend the books by Bruce Eckel for learning more about the C++ language itself, although they concern the langauge and not any specific OS.
Good luck, and have fun!
P.S. I love programming!
INTP
|
|
|
|
|
Thanks to everyone for their replies. Although I don't think that books can help me out any more because I am stubborn and never learn until I make the mistake. John's comment about creating another member function to get the details from the private members sounds the best way (don't know why I didn't think of it myself...been at it for 10 hours today, probably that's why!)
Thanks, again.
|
|
|
|
|
I would like to know if it is possible to have BOTH VC++ 7.1 and VC++ 6 installed on the same computer without anything going haywire?
|
|
|
|
|
Dunno why no-one has responded - am I the only one who does this ? I've run both for months with no hassles.
Christian
I have drunk the cool-aid and found it wan and bitter. - Chris Maunder
|
|
|
|
|
Same here. Works perfectly!
As a matter of fact, I literally have VC 6, and VS .NET 2002 and just recently installed VS .NET 2003 as well and I've had no problems.
|
|
|
|
|
Yes, all three versions 6, 7, and 7.1 work just fine. We have a few systems at work running all three versions.
Tim Smith
I'm going to patent thought. I have yet to see any prior art.
|
|
|
|
|
I'm trying to make an application that uses a speech recognizer engine but it should write from a .cpp file in the dialogbox defined in other .cpp file and I don't know how could I do.
Here is some of my code so you can understand me better:
In my main code1.cpp I have defined a edit box with a member variable. In my code it appears on this way:
<br />
CIVOCOMDlg::CIVOCOMDlg(CWnd* pParent )<br />
: CDialog(CIVOCOMDlg::IDD, pParent)<br />
{<br />
m_strHeard = _T("");<br />
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);<br />
}<br />
<br />
void CIVOCOMDlg::DoDataExchange(CDataExchange* pDX)<br />
{<br />
CDialog::DoDataExchange(pDX);<br />
DDX_Text(pDX, IDC_GOT, m_strHeard);<br />
}<br />
Then in this code1.cpp I create a Grammar object:
<br />
BOOL loadGrammar( TCHAR *pszFile, BOOL bDictGram,<br />
ISRGramCommon **ppISRGramCommon )<br />
{<br />
...<br />
IUnknown * pIUnkGram;<br />
CGramDictSink *pGramDictSink = new CGramDictSink(NULL);<br />
pGramDictSink->AddRef();<br />
<br />
hRes = g_pISRCentral->GrammarLoad( SRGRMFMT_DICTATION, sData,<br />
pGramDictSink, IID_ISRGramNotifySink,<br />
&pIUnkGram );<br />
<br />
pGramDictSink->Release();<br />
...<br />
hRes = pIUnkGram->QueryInterface( IID_ISRGramCommon,(void **)ppISRGramCommon );<br />
pIUnkGram->Release();<br />
<br />
hRes = (*ppISRGramCommon)->Activate( NULL, FALSE, NULL );<br />
<br />
return SUCCEEDED( hRes );<br />
}<br />
In the code2.cpp file I have:
<br />
STDMETHODIMP CGramCFGSink::PhraseFinish( DWORD dwFlags,<br />
QWORD ,<br />
QWORD ,<br />
PSRPHRASE pSRPhrase,<br />
LPUNKNOWN )<br />
{<br />
if( !( dwFlags & ISRNOTEFIN_RECOGNIZED ) ||<br />
!( dwFlags & ISRNOTEFIN_THISGRAMMAR ) )<br />
{<br />
return S_OK;<br />
}<br />
<br />
PSRWORD pSRMax = (PSRWORD)( (BYTE*)pSRPhrase + pSRPhrase->dwSize );<br />
PSRWORD pSRWord = (PSRWORD)( pSRPhrase->abWords );<br />
TCHAR szText[256] = { _T('\0') };<br />
int nWords = 0;<br />
while( pSRWord < pSRMax )<br />
{<br />
if( nWords++ != 0 )<br />
_tcscat( szText, _T(" ") );<br />
<br />
_tcscat( szText, pSRWord->szWord );<br />
pSRWord = (PSRWORD)( (BYTE *)pSRWord + pSRWord->dwSize );<br />
}<br />
<br />
SetDlgItemText(m_hDlg, IDC_GOT, "Unrecognized\0");<br />
return S_OK;<br />
}<br />
This SetDlgItemText(m_hDlg, IDC_GOT, "Unrecognized\0"); doesn't work... It should write in the edit box the text "Unrecognized" whichever I say. I don't know what could I do so it works. Please, help me!
Thank you!
I have no idea
|
|
|
|
|
I'd like to make and edit control that only allows numeric entry with nothing else. Is the best way to do this through subclassing or simply deriving my control from CEdit. Also, what are the advantages or each? I'm new to this whole subclassing thing so I'm not really sure what it's best used for. Thanks in advance.
- monrobot13
|
|
|
|
|
If the edit control is on a dialog box, select the styles property tab in the resource editor and check number. This only applies to integer values though and not floating point or doubles values.
If you need to validate that the contents will only be values of the form "00.00", then you will need to derive you own class from the edit control and override entry validation. In this case I sugest a search of codeproject and its' afiliates to find articles on overriding the edit control, who knows may be someone has already solved the problem for you.
INTP
|
|
|
|
|
If you only want to use integers then the previously mentioned solution is definitely best. However if you want to use floating point numbers then you need create your own class derived from CEdit. You then must overload one function..the OnChar() function. This is called when the WM_CHAR message is passeg to your edit control. In the OnChar() function put the following..
void CNewEdit::OnChar(UINT nChar,UINT nRepCnt,UINT nFlags)
{
// Ascii character for 0-9 is 48 to 57 inclusive
//Allows num characters and the backspace and delete chars
if(((nChar >= 48)&&(nChar <= 57))
||(nChar == 127)||(nChar == 8))
{
CEdit::OnChar(nChar, nRepCnt, nFlags);
}
// only needed if floating point numbers being used.
// 46 is ascii code for '.'
if(nChar == 46)
{
// Get the existing text
char line[100];
LPTSTR buffer = line;
this->GetLine(0,buffer);
CString str = line;
// check if '.' is already present
if(str.Find('.') == -1)
{
int lineLen = this->LineLength();
// if no numbers already put a zero first
if(lineLen == 0)
{
this->SetSel(0,0);
this->ReplaceSel("0.");
}
else CEdit::OnChar(nChar, nRepCnt, nFlags);
}
}
}
its not perfect code but it does the job fine.
Then just add an edit control to your dialog and define a member variable(control) for your edit and it should work fine.
|
|
|
|
|
Thanks for the replies folks. It's put me on the right track.
- monrobot13
|
|
|
|
|
I have run into a strange memory overrun problem.
Note: The following example code may not reproduce the problem,
they are for illustation only.
Note: There are no compiler errors generated by either of the following
2 cases.
CASE 1: TEST_CTESTCLASS define in Test.cpp file.
Bounds Checker reported an overrun, when my application existed.
The VC++ 6.0 debugger does not show m_pTestClass1 as being a
member of CTestClass2 and yet I can still set it to NULL, with no
complants. If I do not set it to NULL, there is no overrun reported.
Note: The variable type CTestClass2 is declared as a member of a
CScrollView derived class. If the member is removed and made global,
then the overrun is not reported.
#ifndef __TEST_H__
#define __TEST_H__
class CTestClass1
{
int m_donothing;
public:
CTestClass() : m_donothing(0) {}
};
class CTestClass2
{
#ifdef TEST_CTESTCLASS
CTestClass1* m_pTestClass1;
#endif
public:
CTestClass2();
}
#endif // __TEST_H__
#include "stdafx.h"
#define TEST_CTESTCLASS
#include "Test.h"
CTestClass2::CTestClass2()
{
#ifdef TEST_CTESTCLASS
m_pTestClass1 = NULL;
#endif
}
CASE 2: TEST_CTESTCLASS define in Test.h file.
In case 2 below Bounds Checker reports no overruns and the VC++ 6.0
debugger shows m_pTestClass1 as being a member of CTestClass2.
#ifndef __TEST_H__
#define __TEST_H__
#define TEST_CTESTCLASS
class CTestClass1
{
int m_donothing;
public:
CTestClass() : m_donothing(0) {}
};
class CTestClass2
{
#ifdef TEST_CTESTCLASS
CTestClass1* m_pTestClass1;
#endif
public:
CTestClass2();
}
#endif // __TEST_H__
#include "stdafx.h"
#include "Test.h"
CTestClass2::CTestClass2()
{
#ifdef TEST_CTESTCLASS
m_pTestClass1 = NULL;
#endif
}
Does anyone have a clue as to what is causing this problem?
Thanks for any hints, etc..., that you can give me.
INTP
|
|
|
|
|
A couple of things I noticed:
- Shouldn't the compiler complain that definition for CTestClass2 is not terminated by a ; ?
- In general its bad mojo to put #ifdef s in the middle of a class definition. Change your compiler directives and you have a class with the same name but different addresses. You'll get random memory access violations with this type of object.
In fact the second thing is what is going on. The first example you only enable the directive when you compile just that file. In essence, what you defined and what you compiled don't match and hence the memory violation. Any other file that includes this will believe the object is defined the wrong way. The second one is "foolproof" since any inclusion will enable the directive.
As I said, its bad mojo to have precompiler directives in the middle of your definition. You really should avoid it to avoid problems just like this.
|
|
|
|
|
Thanks!
My brain must have been out to lunch! As soon as I read your answer it all became clear. Why I did not realize this for myself, I do not know.
Tom Larsen wrote:
- Shouldn't the compiler complain that definition for CTestClass2 is not terminated by a ; ?
:-DSorry about that! It was just an illustration of the problem, not the actual code that created it.
Tom Larsen wrote:
As I said, its bad mojo to have precompiler directives in the middle of your definition. You really should avoid it to avoid problems just like this.
Normaly I do not do this sort of thing. In this case, however, the code used to generate some data for analisys required direct access to member variables to produce the required charts.
I do not like the solution I came up with and will try to find a better way.
Thanks again!
INTP
|
|
|
|
|
What I recommend in cases like this is to wrap the entire class definition for both versions in #ifdef and then make typedef the type to the name you need. It is easier to manage a typedef than it is to manage and entire class that has its internal possibly changing. It also makes problems easier to track down because the code won't compile or link if the pre-compile directives are out of wack.
|
|
|
|
|
I am looking for a sample of adding "Start parameters" to a window service.
|
|
|
|
|
Services actually process 2 command lines.
(1) There's the old command line that you specify upon starting the program. A full command line that the service control manager uses to start your service.
(2) "Start Parameters" which the Service control manager passes to your service's dispatcher (the one you specify via StartServiceCtrlDispatcher() ). The "start parameters" are the ones that you see (and you can 'set') in the Services control panel.
I only use #1 -- which is parseable in the old fashioned argc/argv way. I don't see much use for the "start parameters" way....
Does this help? or confuse?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />
Peter Weyzen<br />
Staff Engineer<br />
<A HREF="http://www.santacruznetworks.com">Santa Cruz Networks</A>
|
|
|
|
|
Hi everyone,
I have a class like this:
class CFoo
{
public:
CFoo();
~CFoo();
BOOL SortByName();
protected:
std::vector<CRec*> m_Recs;
private:
struct NameComparer
{
bool operator()(const CRec* A,const CRec* B)
{
return ((A->m_strName) < (B->m_strName));
}
};
};
BOOL CFoo::SortByName()
{
std::stable_sort(m_Recs.begin(), m_Recs.end(), NameComparer());
return TRUE;
}
Now, basically, I am trying to properly write and use a predicate function (I think that's what they're called; please correct me if I'm wrong) in the context of calling std::stable_sort (and just std::sort for that matter). There are many helpful examples around, but they don't seem to cover dealing with a non-trivial class (or if they do I haven't 'gotten it' yet).
In my case, I want to be able to sort the vector of CRec 's according to several different CRec member variables (different CString s, int s, double s, etc.). My questions are:
1) Did I use proper coding techniques to solve the problem as I have shown here?
2) Is it the case that I need to add additional struct s under the private section of CFoo for each comparison CFoo member function I want to write (with the comparisons applied to the std::vector m_Recs and based on the CRec members themselves actually)?
3) Why do I need to wrap the comparison functions in a struct? How does that fact relate to operator() , etc.?
Thank you all again for reading and giving any advice,
Best,
Eric
|
|
|
|
|
It's usually best to wait a few days before posting the same question again. And, surprisingly, an answer may not be know by the current CP members!
A rich person is not the one who has the most, but the one that needs the least.
|
|
|
|
|
Hi David,
I know. And I knew that I risked being rude, but I figured that since it was late when I left the post it might not get seen by many, so I took the chance.
Anyhow, I take your point and I appreciate your feedback.
Best,
Eric
|
|
|
|
|
Cloaca wrote:
And I knew that I risked being rude...
It was being rude per se, it's just that with timezone differences and the like, it may take two full days before the post has been digested by everyone.
A rich person is not the one who has the most, but the one that needs the least.
|
|
|
|
|
You are right David. That's a good point also. I should male it a policy not to repost for a week or so I guess.
Thanks again,
Eric
|
|
|
|
|
In sum, your solution is okay. In general, check out these books for in-depth explanation on STL.
The C++ Standard Library : A Tutorial and Reference by Nicolai M. Josuttis
Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library by Scott Meyers
Kuphryn
|
|
|
|
|