|
Yeah its taken me over a month to really grasp the whole pattern and how it meshes with traditional C++ semantics. Its not helpful when you try to find stuff about the Dispose pattern and end up with C# examples mixing terms to create more confusion. On the plus side, now C++/CLI basically works just like you would expect native C++ to in most cases and you only need to worry about finalizers for classes with unmanaged members. Certainly an improvement over MC++ (as most things are).
|
|
|
|
|
Yes indeed, there is a destructor-like syntax, but it is actually called a finalizer;
it is a bit confusing if you ask me.
And as you said it has undeterministic behavior: It gets executed by the gc
when it decides to collect the object.
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips:
- make Visual display line numbers: Tools/Options/TextEditor/...
- show exceptions with ToString() to see all information
- before you ask a question here, search CodeProject, then Google
|
|
|
|
|
Michael Chapman wrote: That just seems totally counterintuitive to using managed code.
Yes, but so is mixing native types and having destructors.
The garbage collector will only cleanup managed objects if you don't specifically call a destructor.
Since you don't need deterministic cleanup of your native object, the smart pointer is a good solution,
since it provides the destructor/finalizer for you.
Only if you needed deterministic cleanup of your native object would you need to implement a destructor
and possibly a finalizer as shown in the article (although you do it implicitely with the smart pointer).
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
|
Interesting! Thanks for the link George!
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
hmm...my Sunday morning reply made no sense - I'll take another crack at it.
What I meant to say was...
If you have unmanaged resources in a managed class then you'll need a way to
free them, as always.
You could just cleanup your native resources in the destructor BUT the destructor
won't be called unless you explicitly call it (using delete or calling it directly).
Having to do THAT would be counterintuitive
To ensure your native object created with new gets deleted, you should implement
a destructor AND a finalizer in its managed owner class - that's what Nish's smart pointer
class does for you.
That way you don't have to explicitly destruct your managed object. If it is left
for the GC to cleanup, the GC will call the finalizer (NOT the destructor!)...
ref class MyRefClass
{
int *NativeIntArray;
public:
MyRefClass() {NativeIntArray = new int[400];}
~MyRefClass() {this->!MyRefClass();}
!MyRefClass() {delete[] NativeIntArray;}
} Cheers,
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
OK. I'm making a DLL with a bunch of Win forms controls. The project is in C++/CLI, compiled with the "/pure" switch.
I made a control that contained a TextBox, and two Panels. Each panel has a background image, which I set up using the BackgroundImage property in the "Properties" window. I built the project, the custom control shows up in my toolbox, life is good.
Now, I went to make a second control that uses multiple instances of the first. I added a new "User Control" item to the project and went into design view. I went to the toolbox, and tried dragging an instance of Control1 onto Control2. What an ugly error message:
Failed to create component 'Control1'.... Could not find any resources appropriate for the specified culture or the neutral culture. Make sure 'MyNamespace.MySubnamespace.Control1.resources' was correctly embedded or linked into assembly 'MyAssembly' at compile time, or that all satellite assemblies required are loadable and fully signed.
What the crap!!!???? I did a little research, and found an article that suggested the compiler was not creating the correct resource file. In fact, the only resource file I could find in the intermediate directory was "MySubnamespace.resources". Fine. So Visual Studio is too stupid to name its own resources correctly. So I selected the "Control1.resx" file, right-clicked and selected "Properties". I changed the intermediate file name to be "MyNamespace.Mysubnamespace.Control1.resources", as the error message seemed to suggest was required.
Guess what? I still get the same error message!!!! Can someone explain or point me to a GOOD article on what I'm doing wrong and how to resolve it?
By the way, I don't get that error message once I take out the panel background images. It's obviously a problem with linking the resource file that contains the background image data.
Thank you.
-- modified at 13:00 Saturday 11th August, 2007
|
|
|
|
|
When does the assignment operator get called as opposed to the default ctor? For example, the first line calls the default ctor while the second calls the assignment.
<br />
MyClass theObj = 5;<br />
theObj = theObj;<br />
TIA
I am a SysAdmin, I battle my own daemons.
|
|
|
|
|
Like the name implies, a constructor constructs an object.
You're constructing an object on the first line.
The second line is an assignment (explicitly using the assignment operator).
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
why does the returned object have to be const?
<br />
const Counter Counter::operator++(int)<br />
{<br />
Counter temp(*this);<br />
++itsVal;<br />
return temp;<br />
}<br />
TIA
I am a SysAdmin, I battle my own daemons.
|
|
|
|
|
I don't think it should be const. Where did you see that form?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
hi,
I think it is to prevent the following ambigius code snippit
<code>Counter count;
Counter foo = count++;
count++++;
codito ergo sum
|
|
|
|
|
Hi,
I have the following code that won't compile with the error:
e:\PROGRAMMING\SANDBOX\RTTI\dynamic_cast1.cpp(31): error C2683: dynamic_cast : 'A' is not a polymorphic type
<br />
#include "stdafx.h"<br />
<br />
using namespace std;<br />
<br />
class A { };<br />
<br />
class B { };<br />
<br />
void f()<br />
{<br />
A* pa = new A;<br />
B* pb = new B;<br />
void* pv = dynamic_cast<void*>(pa);<br />
pv = dynamic_cast<void*>(pb);<br />
}<br />
<br />
int main()<br />
{<br />
return 0;<br />
}
It's an example in VStudio and is expected to work. Can anyone help me make sense of the error message? TIA!
I am a SysAdmin, I battle my own daemons.
|
|
|
|
|
sorry I just found out the solution, to use dynamic_cast on an expression the underlying object must have at least 1 virtual function.
-- modified at 7:49 Saturday 11th August, 2007
however the following is supposed to cause a runtime exception but doesn't:
<br />
class E<br />
{<br />
public:<br />
void func()<br />
{<br />
cout << "func from E" << endl;<br />
}<br />
};<br />
<br />
class F<br />
{<br />
public:<br />
void func()<br />
{<br />
cout << "func from F" << endl;<br />
}<br />
};<br />
<br />
<br />
void f()<br />
{<br />
E* pe = new E;<br />
F* pf = dynamic_cast<F*>(pe);
}
as well as the following (works but shouldn't because pB is just an instance of B)
<br />
#include "stdafx.h"<br />
<br />
using namespace std;<br />
<br />
<br />
class B <br />
{<br />
public:<br />
int BMem;<br />
void funcB()<br />
{<br />
BMem = 2;<br />
cout << "funcB: " << BMem << endl;<br />
}<br />
};<br />
<br />
class D : public B <br />
{ <br />
public:<br />
int DMem;<br />
void funcD()<br />
{<br />
DMem = 4;<br />
cout << "funcD: " << DMem << endl;<br />
}<br />
<br />
};<br />
<br />
void f(B* pb, D* pd)<br />
{<br />
D* pd2 = static_cast<D*>(pb);
pd2->funcD();<br />
<br />
B* pb2 = static_cast<B*>(pd);
pb2->funcB();<br />
}<br />
<br />
int main()<br />
{<br />
cout << "Main - Start" << endl;<br />
<br />
B* pB = new B;<br />
D* pD = new D;<br />
<br />
f(pB, pD);<br />
<br />
cout << "Main - End" << endl;<br />
}<br />
its output is:
<br />
Main - Start<br />
funcD: 4<br />
funcB: 2<br />
Main - End<br />
-- modified at 8:36 Saturday 11th August, 2007
I am a SysAdmin, I battle my own daemons.
|
|
|
|
|
Hi, I am using visual Studio 2005 C++/CLI. What is available to help me format my output to the printer. I keep finding read only properties. I can use PageScale() to get the display output to fit on the printed page but the printed output is "scrunched up". I have tried playing with PrinterSettings::CreateMeasurmentGraphics() with no success. Is using this function the right approach?
Thanks,
Buck
Buck
|
|
|
|
|
Hi, I'm using visual Studio C++/CLI. I found an example in Visual Basic and followed these steps. Using the Toolbox in the form designer I added printDialog1 and printDocument1 to my Form1. Then I modified printDialog1 and set the AllowSelection and AllowSomePages properties to true and the Document property to printDocument1. This association would seem to imply that printDocument1 would contain the contents of Form1 but evidently it doesn't. I set up the fileToolStripMenuItem to have a printToolStripMenuItem and then double clicked on it to get the function header and modified it as follows...
private: System::Void printToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e)
{
if(printDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK)
printDocument1->Print();
}
This prints a blank page. How do I associate the graphics on my screen with printDocument1 so it will actually come out of the printer? I know this is probably incredibly trivial but most people don't document the trivial. For example, in order to be able to paint I needed to know the screen size. After googling "C++ .NET display size" I got no help. Then I tried "C++ .NET screen size" and still didn't find anything. After an hour or so I stumbled onto Screen::Bounds. I didn't even know the Screen class existed! I have five texts on C++ 2005 and none of them list the Screen class in the index (or a lot of other classes that I have found by accident that seem to be important or useful). So I would not be surprised if there is a command that takes the information from the screen and copies it to printDocument1, but is so basic that everyone knows how to do it already, everyone except the people that have never done it before. What's the $64,000 answer here?
Thanks
Buck
|
|
|
|
|
Hi Buck,
I will find you where ever you go...
For 64K$ I would say:
it all depends on the correlation between a document on screen and a document on paper.
Some programs keep them identical (e.g. MS Word can show what it will print almost
exactly). Other apps don't care, they show one thing, and print an equivalent but
completely different thing.
I have a simple case in my Sokoban article; it displays a board game (that fits on
a screen, no scrolling involved), and can print it on one page.
The essence is you reuse the code that currently sits in your OnPaint handler (it
will require a minor reorganization, splitting the top few lines from the body).
If your wafer would fit on one page, even when it needs some scrolling on screen,
I strongly suggest you have a look at my article's code.
Greetings
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips:
- make Visual display line numbers: Tools/Options/TextEditor/...
- show exceptions with ToString() to see all information
- before you ask a question here, search CodeProject, then Google
|
|
|
|
|
I read the article and looked at the source code. It wasn't any help. There is no handler named OnPaint. Bottom line is all I can print are blank pages.
Buck
|
|
|
|
|
Hi Buck,
in LP_Sokoban's file Board.cs there is a line
Paint+=new PaintEventHandler(Board_Paint);
which is an alternative way to install a paint handler; in this case it is called
Board_Paint, and it expects to get two arguments, rather than one, but apart from
that it is identical to an OnPaint() method, which is the normal way of installing
a paint handler in a derived class.
And as you can see it immediately calls another method
public void Painter(Graphics g, int panelWidth, int panelHeight, int<br />
fillPercentage, bool printing) passing not the eventargs thing, but the
actual values it needs.
Same Painter method also gets called by PrintableBoard_PrintPage() which is the
PrintPage handler for my public class PrintableBoard : PrintDocument ;
this handler too get installed explicitly, hence its name differs from OnPrintPage.
Hope this helps.
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips:
- make Visual display line numbers: Tools/Options/TextEditor/...
- show exceptions with ToString() to see all information
- before you ask a question here, search CodeProject, then Google
|
|
|
|
|
Hi Luc,
Thanks for the info. While you were responding I was digging into another article that showed an additional function that I did not have called printDocument1_PrintPage(). Seeing that this function had the same general naming convention as other Form1 design controls, I went back to the Form1 design page and double-clicked on printDocument1 and the following code was added...
private: System::Void printDocument1_PrintPage(System::Object^ sender, System::Drawing::Printing::PrintPageEventArgs^ e)
{
DisplayWaferMap(e->Graphics); // I added this line and began receiving printed output
}
Granted, the size of the printed page has to be scaled correctly but at least now I am getting printed output.
Thanks again,
Buck
|
|
|
|
|
Seems like your e-mail notification problem got fixed ?
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips:
- make Visual display line numbers: Tools/Options/TextEditor/...
- show exceptions with ToString() to see all information
- before you ask a question here, search CodeProject, then Google
|
|
|
|
|
hi i am having a 3d mesh .x file. how to load this using directx managed code. i am new to directx please help me.
|
|
|
|
|
need help regarding a project. me n a friend of mine r thinking to make a voice for converting voice into text as our final year project can i get help regarding it, like what all r we supposed to do. plz do help me need it quick
Never follow anyone but learn from everyone
|
|
|
|
|
good luck with that, I'm sure you won't fail to impress
|
|
|
|
|
I don't want to crush your creativity or anything but Voice Recognition software is very hard to make. I think if you had the knowledge and skills to pull it off you wouldn't be asking here.
Thats not ment as an insult, I cirtainly couldn't pull off making that sort of software in a short time frame and probably could never pull it off by myself, just as a reality check.
You'd be much better off picking something small and simple that you can complete and do well. A large unfinished and badly coded project will get you much worse marks.
|
|
|
|