|
hmmm I'm drawing a blank on enforcing the call before any constructor.
Here's what I was thinking previously - this example
uses a common base class instead of duplicating the
constructor/destructor code in every class...
void CallMeFirst()
{
}
void CallMeLast()
{
}
class CommonBaseClass
{
static int RefCount;
protected:
CommonBaseClass()
{
if (0 == RefCount)
CallMeFirst();
RefCount++;
}
~CommonBaseClass()
{
RefCount--;
if (0 == RefCount)
CallMeLast();
}
};
int CommonBaseClass::RefCount = 0;
class SomeClass : public CommonBaseClass
{
public:
SomeClass() {}
~SomeClass() {}
};
Close to your spec, but close only counts in horse shoes and hand grenades
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Can't see much wrong with that Mark, I wrote a story, you wrote the code, seems to be what I'd in mind too. I suppose it's single threaded. Can't see it break, except when components break, but that's an error handling issue.
Bram van Kampen
|
|
|
|
|
That looks like it might do the trick, Mark. Thanks a lot. I'll put together a test of this in the next couple of days and see how it goes. Really appreciate the help.
Chris Meech
I am Canadian. [heard in a local bar]
In theory there is no difference between theory and practice. In practice there is. [Yogi Berra]
|
|
|
|
|
Cool. Just a reminder (as Bram mentioned) - it's not
thread safe, although you can sync access to the ref count
if you need it thread safe.
Cheers,
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
In this Architecture, why not put the CallMeFirst and CallMeLast in a Base class. The Baseclass Constructor is always called before the object constructor, The Baseclass Destructor is always called after the object Destructor. The Info is scarce, hard to know what the OP wants to achieve. BTW Your code will only leak if DoSomeStuff breaks.
Bram van Kampen
|
|
|
|
|
Looks like we're thinking the same thing.
Chris wants the CallMeFirst() called before any
constructor though...
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Thanks for your additions to all of this Bram. I think what Mark put together will do the trick for me. You guys deserve 6's for your help.
Chris Meech
I am Canadian. [heard in a local bar]
In theory there is no difference between theory and practice. In practice there is. [Yogi Berra]
|
|
|
|
|
Your Info is schetcy, but I would use a static reference counter, starting at 0. CallMeFirst sets this to 1, Each Constructor first checks that it is not 0 to confirm that CallMeFirst has been Called. Each Destructor decrements the value, and checks if it is 1. If the Destructor finds the RefCount 1, it sets the RefCount to 0, and calls CallMeLast. A Good way of implementing this would be to use Multiple Inheritance, and also derrive each class from CRefCount.
Bram van Kampen
|
|
|
|
|
I am trying to get the information from this printf statement and place it in another one can anyone help.
I can't believe I can't see how to do this.
I want to take the information from "part8" in this statement:
float distance_between(struct place * a, struct place * b)
{
float ptrs here.....
math here.......
printf( "Result is: %9.2f \n", part8 );
}
Now I want to take my information from "part8" above and place it to "dist" in this statement :
float dist = distance_between( city_A[i], city_B[i] );
printf(" %s and %s is %d km\n",city_A[i]->name,
city_B[i]->name, dist);float dLat1 = a->lat;
can anyone help?
|
|
|
|
|
You just need to return the float value:
float distance_between(struct place * a, struct place * b)
{
float calculated_distance = 0.0;
float ptrs here.....
math here....... (calculate the distance)
return calculated_distance;
}
Hope that helps.
Karl - WK5M
PP-ASEL-IA (N43CS)
PGP Key: 0xDB02E193
PGP Key Fingerprint: 8F06 5A2E 2735 892B 821C 871A 0411 94EA DB02 E193
|
|
|
|
|
Thanks I realized after I sent the question all I had to do was
return part8; and it worked
Thank you for the reply though really appreciate it.
|
|
|
|
|
Hi. Can you clear something up for me?
My collegue is declaring vars inside while loops (and maybe in for loops as well...)
Does this allocate new memory each time for the variable and hence considered wasteful?
Example:
while (m_socket->Read((char *) buffer, bufferLength, false, &from) > 0) {
UINT portNumber = ntohs(from.sin_port);
ProcessMessage(buffer, portNumber);
}
compiling in C++, VisualStudio 2005
Thanks.
|
|
|
|
|
You should really check the generated machine code to be 100% sure, but I bet money it will be exactly the same as if you put the portNumber declaration before the loop. Compilers are pretty smart these days
|
|
|
|
|
Nemanja Trifunovic wrote: it will be exactly the same as if you put the portNumber declaration before the loop. Compilers are pretty smart these days
Sorry, this is incorrect. If you put portNumber outside the loop, it's scope will be larger. This has nothing to do with smart compilers, but with the semantics of cpp.
Bram van Kampen
|
|
|
|
|
Bram van Kampen wrote: Sorry, this is incorrect.
Sorry, it is correct
Bram van Kampen wrote: If you put portNumber outside the loop, it's scope will be larger.
True, but that will have an effect on the generated machine code only if it is actually used in that larger scope.
|
|
|
|
|
Not wanting to split hairs, there's more to CPPCode than the eventual Machine code. (Readibility, Intent, Scope, etc). It will probably generate similar machine code, in particular in the quoted example. If the var where a class with a non-trivial constructor, in theory the Constructor / Destructor would be called each for each itteration of the loop, unless if the Optimiser decided that nothing was to be gained by this, and rearranged the machine code to place it outside the loop. As for scope, well, that's clear forsofar as the scope brackets are concerned. There has been confusion in the past about the scope of a var declared in the test statement of a loop (e.g. for(int i=0;;) In older MS compilers, this particular case left the Symbol Table in an inconsistent state. You could not declare a New i,(Already Declared), Nor use the Old one(Undeclared Identifier.
Bram van Kampen
|
|
|
|
|
Actually you are both correct, the language clearly defines scope and how variables should be accessed inside these scope regions. But there is a difference between language semantics and compiler output. Especially when optimization is involved.
Optimizing compilers such as MSVC can unroll loops, change/combine variables or eliminate them completely. In fact some compilers may choose to completely remove some of your function calls. SecureZeroMemory [^]exists for this very reason as you can plainly read in its documentation.
Microsoft has only recently made a modest attempt to adhere to ISO standards. In fact Microsoft only recently added Force Conformance in for Loop Scope[^] I believe in VC2005. Prior compiler releases allowed out of loop scope variable reuse.
Keep in mind that almost all compilers are not fully ISO conformant and they all optimize differently. Here is an excellent article over at Dr. Dobb's[^] illustrating the history of ISO compiler conformance.
Best Wishes.
-David Delaune
|
|
|
|
|
Yes, but you have to start somewhere. ISO is a good starting point. MS might not always comply, thats where you deviate from the starting point.
Bram van Kampen
|
|
|
|
|
No, it does not! After ProcessMessage() returns, the code hits the '}' the scopr with portNumber in it is destroyed. Then the 'while'test is done, and, if TRUE, the code this the'{ starting the scope again, and constructing the var portNumber all over again. This is sort of trivial with UINTS, these have trivial default Constructors and Destructors. In case of classes, you will have the overhead of the Constructor / Destructor Call.
Bram van Kampen
|
|
|
|
|
Hi Friends,
Few days back i have installed visual studio 2008 on my machine.
When i tried to build the samples, i am unable build any solution.
I am getting
Rebuild All: 0 succeeded, 0 failed, 1 skipped. for every solution .
can someone help me in fixing the issue.
Thanks in advance.
Appu..
"Never explain yourself to anyone.
Because the person who likes you does n't need it.
And the person who dislikes you won't believe it."
|
|
|
|
|
|
hello my friends,
i am no a advanced Visual C++ developer, but i am only a new VC++ / MFC developer (starting from 15 jun 2008)
please:
ho to host a ActiveX Control in my MFC View Class ?
otherwise:
ho to add a other controls to my MFC View ?
(this is a generik View, (no RichEdit, Edit or HTML View)
thanks!
|
|
|
|
|
Hello, I'm pretty new to programming. I have 2 programs: a server and a client. i want the server to accept messages and do any message processing on a different thread while i keep it's main thread available to whatever i want (this is only something i'm doing to get accustomed with threads & sockets). So, i have an AbstractStream class which is inherited by an ServerStreamSocket class and a AbstractServerCommsThread class which is base class for ServerSocketCommsThread. In the main of the program i create a ServerStreamSocket * ss and after initalising the socket i pass it the thread to be used: ServerSocketCommsThread *thr = new ServerSocketCommsThread(ss). The thread should be started by thr->Run(). Run()creates a thread using a friend function ThreadMe to which it passes a pointer to the object so the threading class has acces to the ServerStreamSocket. Now, i tried doing something really stupid in the threaded function, like outputting a character for 400 time and outputting a different character in the main function to see if they are sequential or not, and unfortunately they are sequential. Any idea why this is?
Here the threading class implementation and the main function:
int main()
{
ServerStreamSocket *ss = new ServerStreamSocket();
ss->init(11000);
ServerSocketCommsThread *sockThr = new ServerSocketCommsThread(ss);
sockThr->Run();
for (int i = 0; i < 400; i++)
cout << "o ";
return 0;
}
class ServerSocketCommsThread : public AbstractServerCommsThread
{
private:
AbstractStream *stream;
pthread_t tid;
public:
void Run();
public:
ServerSocketCommsThread( AbstractStream *pAS);
~ServerSocketCommsThread();
//threaded function must be static or global
friend void* ThreadMe(void *arg);
};
ServerSocketCommsThread::ServerSocketCommsThread( AbstractStream *pAS)
{
this->stream = pAS;
}
void ServerSocketCommsThread::Run()
{
pthread_create(&tid, NULL, ThreadMe, (void*)this);
//return;
}
void* ThreadMe( void *arg)
{
ServerSocketCommsThread *hdl = (ServerSocketCommsThread*)arg;
char in[300];
hdl->stream->write("Starting thread", 300);
cout << "thread started!";
/*char recBuff[300];
while(1){
hdl->stream->read(recBuff, 300);
cout << recBuff << endl;
}*/
for (int i = 0; i < 400; i++)
cout << "x ";
}
|
|
|
|
|
tiberiuv wrote: Now, i tried doing something really stupid in the threaded function, like outputting a character for 400 time and outputting a different character in the main function to see if they are sequential or not, and unfortunately they are sequential. Any idea why this is?
If I understand you correctly you believe you have a problem because you get an output that consists of 400 'x' followed by 400 'o', or the other way around....
Right?
Consider that the scheduler lets each thread run for approx. 10ms unless the thread is preempted by another thread with higher priority that is ready to run.
This means that your threads have plenty of time to write 400 chars to the console, or output window, before the next thread is allowed to run.
This is not a problem in your code or the POSIX thread library, this is how the OS works.
Can you pin-point in a few sentences (less than ten and without code initially) what your undesired behaviour is, you'll get more answers.
The heading of your post suggests that it's about POSIX threads, but I don't see any problem related to the use of them.
(Just for the record: yes, I've used the POSIX thread library port for Win32.)
"It's supposed to be hard, otherwise anybody could do it!" - selfquote "High speed never compensates for wrong direction!" - unknown
|
|
|
|
|
Thanks for the answer. My desired behavior was to actually see that a separate thread is created and that the output from the thread is intertwined with the output from the main thread. I had the impression i had done this before and it worked (by creating two threads directly from the main function) but it's getting clear to me that this is not the case
And yes, it wasn't a POSIX threads question as much as it was a threading question. But right now it's clear to me what is happening. Thank you.
|
|
|
|