|
Brilliant. Thank you.
cheers
Chris Maunder
|
|
|
|
|
Named shared memory along with named synchronization objects AND monitoring process handles.
I've had apps with shared memory queues with both sides waiting on a [local] exit handle, a process handle of the other side, a semaphore and perhaps other objects.
For simple monitoring, you could combine a named semaphore and process handle.
|
|
|
|
|
I'm working on a GAME SERVER program. there is a design problem confused me.
Basic Situation:
1. the host object just as bellow has a lot of child objects. eg, 20 child objecs.
2. the host would be new and delete very frequently.
3. all the operations from the child would be invoked like this :
pHost->GetA()->DoSomething(),and also very frequently.
4. CHost1 use objects as child,CHost2 use poniter and new child in constructor.
my question is:
1. since I would new and delete CHost very ofen,may be in the server loop, is CHost2 a bad design?
2. since all the method of the child would be invoked like this:
pHost->GetA()->DoSomething(). is this indirect call cost a lot compare to
pHost->DoSomething, because it happens a lot.
If CHost2 is a bad design, I would use CHost1 or use CHost2 and a CHost2 Pool.
If Indirect call cost a lot.I would only use CHost3 without child objects,and all method would be like pHost->Dosomething
Thank you all.
ps I can't use the code button to format the code,I tried chrome and ie,why
class CHost1
{
public:
CHost1(){}
public:
C1* Get1();
C2* Get2();
CN* GetN();
private:
C1 m_1;
C2 m_2;
CN m_n;
};
class CHost2
{
public:
CHost2()
{
m_p1 = new C1;
m_p2 = new C2;
m_pN = new CN;
}
public:
C1* Get1();
C2* Get2();
CN* GetN();
private:
C1* m_p1;
C2* m_p2;
CN* m_pN;
};
|
|
|
|
|
Allocating class members on the heap is not per se bad design. It avoids for example stack overflows when the class is created on the stack and the members use a lot of memory.
But allocating and freeing memory frequently reduces the performance significantly. So the Host2 option seems to be the best option for you. If the members use so much memory that stack overflows might occur, create Host2 always on the heap using new .
The indirections should not be a problem. The overhead is very small compared to heap allocation. Some indirections may be also removed by the compiler. And you might not be able to remove them because with your example I did not see a chance to do that:
CHost::GetA() { return &m_A; }
CA::DoSomething { }
pHost->GetA()->DoSomething();
pHost->&m_A->DoSomething();
pHost->m_A.DoSomething();
CHost::DoSomethingWithA() { m_A.DoSomething(); }
pHost->m_A.DoSomething(); As you can see both methods are not really different.
|
|
|
|
|
It is actually the situation where you use a delegate.
It is very common on game servers which are doing things like guns/projectiles etc to do this. The reason is you want to bind a behaviour to a random class without worrying what the class is and going thru the issue you have. So when I have a bullet I don't care if it's a 50 cal, 45 magnum or a BB pellet it has a behaviour and I will execute the delegate function to move it and use the payload to hold a callback for the object to draw itself and vary the damage etc. The classes don't even have to be related to use a delegate they can have random relationships and it's safe.
So unlike a class/object a delegate is an action or an event and generally it carries a payload which can be other actions or objects. You called your function DoSomething and it goes to another object
The other cute thing is you can add and delete delegates at any time to an object and you can test for the presence of a delegate. So you can add/delete and turn on/off functionality to a class/object with ease without the class itself needing to know or building that functionality on all related classes.
All real game engines do it that way and typically your server connects to players etc via delegates. Usually it is just doing things like scoring etc and removing dead people etc so it doesn't care what the objects are it just needs a couple of things from them. The last thing you want the server doing is get involved heavily in the objects or you will bottleneck everything. When an object disconnects from the server it simply removes itself from the server multicast delegates and the server will no longer see it and it's free to delete itself or whatever in it's own good time. So typically a server doesn't get involved in creating or deleting objects either which is the responsibility of a spawn system(s).
Delegates | Unreal Engine[^]
Unity - Delegates[^](worth watching the video to see it's use in a game)
Unreal Engine has the classical layout (look at the block diagram at bottom) .. GameServer sits alone things only join
Gameplay Framework Quick Reference | Unreal Engine[^]
There are a number of articles on C/C++ delegates on this site and good old google will throw hundreds and obviously MS has a sample as Visual Studio has them.
delegate (C++ Component Extensions)[^]
You might also want to look at C++ Events which we sometimes use in place of a delegate
In vino veritas
modified 11-Jul-17 23:04pm.
|
|
|
|
|
Jochen Arndt,leon de boer
thank you very much,it's really a great help. Now I know how to do it.
|
|
|
|
|
I'm working on a server program. there is a design problem confused me.
|
|
|
|
|
que.1
Delete the least number of integers from a given set of integers so that the product of the remaining integers in the set is a perfect square. In case there is more than one solution then find the solution that gives the largest perfect square. Assume that each integer contains five or less number of digits. The total number of integers in the given set is twenty or less.
Input (Q3.in)
First line will be number of test cases
The input may contain multiple test cases.
For each test case there is a single input line. The line contains the given set of integers. The
Output (Q3.out)
For each test case there is only one output line. The line simply prints the integers to be deleted
in ascending order. There are two special cases; print output for these cases as indicated below.
Case 1: No integer is to be deleted: Print 0 as output.
Case 2: All integers are to be deleted: Print all integers in ascending order.
Sample Input
4
2 3 12 18 24
12 10 15 18
4 12 10 15.
|
|
|
|
|
And what is the question about C or C++?
|
|
|
|
|
Sorry, this site is not here to do people's homework for them. Please make an effort to do your own work, and if you have a specific question with the code you have written, then people will try to help you.
|
|
|
|
|
We do not do your HomeWork.
HomeWork is not set to test your skills at begging other people to do your work, it is set to make you think and to help your teacher to check your understanding of the courses you have taken and also the problems you have at applying them.
Any failure of you will help your teacher spot your weaknesses and set remedial actions.
Any failure of you will help you to learn what works and what don't, it is called 'trial and error' learning.
So, give it a try, reread your lessons and start working. If you are stuck on a specific problem, show your code and explain this exact problem, we might help.
As programmer, your job is to create algorithms that solve specific problems and you can't rely on someone else to eternally do it for you, so there is a time where you will have to learn how to. And the sooner, the better.
When you just ask for the solution, it is like trying to learn to drive a car by having someone else training.
Creating an algorithm is basically finding the maths and make necessary adaptation to fit your actual problem.
The idea of "development" is as the word suggests: "The systematic use of scientific and technical knowledge to meet specific objectives or requirements." BusinessDictionary.com[^]
That's not the same thing as "have a quick google and give up if I can't find exactly the right code".
Patrice
“Everything should be made as simple as possible, but no simpler.” Albert Einstein
|
|
|
|
|
Hello! I'm trying to browse a text file using CMFCEditBrowseCtrl (it is used in CFirstDialog Class) and use this file in another Dialog Class (named CSecondDialog Class). My problem is on how to save the filename retrieved from the CMFCEditBrowseCtrl when the CFirstDialog::OnEnChangeMfceditbrowse1() goes out of scope and then pass the filename to the CSecondDialog. Here is the code:
void CFirstDialog::OnEnChangeMfceditbrowse1()
{
CString str;
m_browser.GetWindowText(str);
}
void CSecondDialog::OnBnClickedOk()
{
CStdioFile fileSource("here I need to put the filename retrieved from the previous dialog class", CFile::modeRead);
CStdioFile fileDest;
CString strLine;
CString strFile;
int num = 1;
while (fileSource.ReadString(strLine))
{
strFile.Format(L"over%d.txt", num++);
fileDest.Open(strFile, CFile::modeWrite);
fileDest.WriteString(strLine);
fileDest.Close();
}
fileSource.Close();
}
|
|
|
|
|
The OnEnChangeMfceditbrowse1 method should store the file name in one of its object variables (or str ) should be an object variable. The calling code can then capture that variable when the dialog returns.
|
|
|
|
|
It depends on how your dialog classes can be accessed and if they both exist at the same time.
A possible solution:
You need to store pointers to your dialogs when they are created (usually in the parent window).
Store the file name in a member variable of CFirstDialog and provide a public function to get the name:
CFirstDialog
{
public:
const CString& GetFileName() const { return m_strFileName; }
protected:
CString m_strFileName;
};
void CFirstDialog::OnEnChangeMfceditbrowse1()
{
m_browser.GetWindowText(m_strFileName);
} Similar for CSecondDialog but there with a set function:
CSecondDialog
{
public:
void SetFileName(const CString& strFileName) { m_strFileName = strFileName; }
protected:
CString m_strFileName;
};
You can now get and set the name from the class that holds the pointers to the dialogs. If both dialogs might not exist at the same time you have to store the file name in a member variable of that class (e.g. get the name when DoModal() returns).
Finally you need access to the upper class from CSecondDialog . If the upper class is the parent window, always of the same type, and has been passed as parent, you can use casting:
void CSecondDialog::OnBnClickedOk()
{
CParentOfDialogs *pParent = static_cast<CParentOfDialogs*>(GetParent());
CString strFileName = pParent->m_pFirstDialog->GetFileName();
}
Otherwise you have to use a member variable in your second dialog that holds a pointer to the upper class and is initalised upon dialog creation or using a set function.
There are also other solutions and variations of the above.
|
|
|
|
|
Is m_pFirstDialog a new variable?
Jochen Arndt wrote: If both dialogs might not exist at the same time you have to store the file name in a member variable of that class (e.g. get the name when DoModal() returns). The two dialogs do not exist at the same time, actually CSecondDialog gets on screen after I finish with CFirstDialog which goes out of scope. Could you explain me how to get the file name after DoModal() returns? Thank you in advance!
void CInputView::OnFirstDlg()
{
CInputDoc* pDoc = GetDocument();
CFirstDialog DialogWindow;
CSecondDialog *pDlg = new CSecondDialog(this);
pDlg->DoModal();
delete pDlg;
}
void CMyView::OnSecondDlg()
{
CMyDoc* pDoc = GetDocument();
CSecondDialog DialogWindow;
DialogWindow.DoModal();
}
|
|
|
|
|
Add a member variable to the first dialog (as already described) and to the parent window. Then get the file name from the dialog after calling:
void CInputView::OnFirstDlg()
{
CFirstDialog DialogWindow;
DialogWindow.DoModal();
m_strFileName = DialogWindow.GetFileName();
}
If you create the second dialog from another class (not CInputView ), you have to pass the name to the other class in a similar way.
Then set the file name before calling DoModal() of the second dialog:
CSecondDialog DialogWindow;
DialogWindow.SetFileName(m_strFileName);
DialogWindow.DoModal();
|
|
|
|
|
I create the second dialog from the CInputView (the same class). I wrote it wrong above. Thank you very much for your help!I'm grateful!
|
|
|
|
|
Could you please explain me how to store pointers to the dialogs when they are created so that I can get and set the name from the class that holds the pointers to the dialogs? I'm sorry for asking again but I got a little confused with this part.
|
|
|
|
|
Such is only useful with modeless dialogs. Modal dialogs will block so that there is usually no need to have a pointer.
However:
if (NULL == m_pSomeDlg)
{
m_pSomeDlg = new CSomeDialog(this);
} When doing so m_pSomeDlg must be initialised with NULL in the constructor and deleted in the destructor.
|
|
|
|
|
What number will z in the sample code given below?
int z, x=5, y= -10, a=4, b=2;
z=x++ - --y *b/a;
Can anyone please solve it and explain the precedence. i am not getting right answer. my answer is 2.5. but it is wrong. i am struggling in it. kindly solve it and explain. Thanks in advance.
|
|
|
|
|
|
thank you. i am clear now
|
|
|
|
|
See C++ Operator Precedence - cppreference.com[^].
The first step is inserting parentheses according to the predence and order:
z = (x++) - (((--y) * b) / a);
Then replace the variables with their values:
z = (5++) - (((--(-10)) * 2) / 4);
Now solve step by step but observe the special handling of the postfix operator which will return a temporary copy that contains the value before the operation (that means x will be changed but the initial value of 5 is used for the calculation). Observe also that results might get rounded wirh integer arithmetic:
z = (5) - ((-11 * 2) / 4);
z = 5 - (-22 / 4);
|
|
|
|
|
parkavikkk wrote: int z, x=5, y= -10, a=4, b=2;
z=x++ - --y *b/a;
Can anyone please solve it and explain the precedence. i am not getting right answer. my answer is 2.5. but it is wrong.
Of course it is wrong! Just because the integer number cannot be 2.5, nor 2.7, nor 2.8...
|
|
|
|
|
Maybe the OP was manually calculating it?
|
|
|
|