Making destructors compatible with C#...

Started by
18 comments, last by arbitus 12 years, 6 months ago
Or you could have a separate method for termination that you need to call explicitly. That way you disentangle the logical 'killing' of an object from the memory management aspects of releasing the object's memory. [/quote]

This is exactly what I would like to accomplish. In C++/C#, deleting one object, I would accomplish it like this:


//C++
#define Delete(Object) {Object->Destroy();delete Object;}
//C#
#define Delete(Object) {Object->Destroy();}


What I'm looking for is some way I can make delete [] work the same way.

My assumption is that I will have to take all my destructor code, and move it into a Destroy() function. Then what I need is a nice seamless way to invoke that destroy function that will be compatible with C++ and C#. I'm looking for a way to cover all my bases, because at some point in the head of coding, I will surely do something like initialize an array, and then go over to C#, days or weeks later, and say, crap... I forgot I wasn't supposed to initialize arrays.

Now, one way I could do it would be a for/next loop:


#define DeleteArray(Object) {for (int aCount=0;aCount<GetObjectCountSomehow;aCount++) {Object[aCount]->Destroy;}}


But given this:


Object *aObject=new Object[25];


...how do I get that 25 elsewhere to iterate through? Is there a good way? Aside from using sizeof(Object array)/sizeof(Object[0])? Because that would add the extra complexity of having to put the class type in the delete, and now we're starting to talk very verbose code.

And, in an IDEAL world, there would be some way to make my delete define work, even on this:


struct Thingie
{
int a,b,c;
};

Thingie *aT=new Thingie;
Delete(aT);


...even though Thingie doesn't have a Destroy() function at all. I would like to accomplish this for simplicity and consistency... and I was wondering if there was some magic preprocessor way to say "if Destroy() is defined, call it, otherwise, don't." I realize this is probably impossible, but like I said, I've seen people accomplish some astounding stuff with preprocessor, so if everyone DID come up with a way, I'd like to know it!
Advertisement
You don't need to make delete[] work. Arrays are evil, seriously.

If you have a vector<shared_ptr<T>> in C++, where T has an empty destructor, you'll behave pretty much like C# Lists.

But seriously, give us a concrete example of what you're doing and we'll give you a concrete answer. Trying to guess how you're abusing destructors in C++ makes it difficult to formulate good advice.
Why are you using defines and attempting to mix C++ and C#?

These two should not coexist in the same file, much less should you attempt to interleave preprocessor keywords.

I think you need to define the problem more clearly, as I have no idea WHY you want to do what you are doing, much less why you are doing it the way you have shown (which has many obvious code smells).
I dunno why "why" has to come up in a tech question with a tech answer, but here goes:

I code in C++. I like C++. It can work on Windows, it can work on iOS, it can work on Linux, the only place it can't work is where Microsoft has decided thou shalt use C# and C# thou shalt use.

I use very vanilla C++. I'm not a trickster with it. Most of my C++ can actually go to Java, even, with minimal changes. The only exception being destructors, which as I said above, I use heavily.

I am trying to make my C++ delete my objects, while at the same time make it so that I can move the whole shebang over to C# if I should need to. I am working toward future compatibility. I am not using C# at this time.

I am trying to give myself a consistent workaround, that I'll call all the time, to delete objects, which won't actually delete them on a managed language, but WILL invoke a "Destroy()" function that I can do housekeeping that I'd normally do in a destructor. I want this set up so I can use it fairly consistently in C++ and C# (small exceptions would be fine).

For my own sanity, I want it compatible with arrays and other stuff, so that I have margin to be sloppy.

Now, I know the Array[] delete is possible... I have a solution above, but was wondering if a better one exists. The "call Destroy()" function thing I want is probably *not* possible, but I'm asking on the chance that someone has ever accomplished that.

On the philosophy of programming: I know "change everything you're doing and do it my way" is always an option. But I am looking for a way to not "change everything I'm doing."

I dunno why "why" has to come up in a tech question with a tech answer,
[/quote]

Because you're doing things that will cause you grief in the future. We're asking 'why' because occasionally that grief is worthwhile to solve a difficult problem or to stop more grief that alternatives would cause you.

In this case though, it just seems as though you're purposefully harming your project due to ignorance, stubbornness, and/or absurd requirements. There is no good tech answer. Porting things is more than changing syntax around. C++ idioms don't translate to C#. C# idioms don't translate to C++. Doing icky things to support something you might want to do in the future is a classic pitfall to avoid.
Porting things is more than changing syntax around.[/Quote]

I've been porting things for years and years. I've been coding since magnetic tape. There is no call for this.

Did you see this?


Most of my C++ can actually go to Java
[/quote]

If I asked you how to render a triangle in OpenGL, would you tell me a DirectX command, or give me an explanation of the virtues of triangle strips vs. triangle lists? There's a specific job I want to do, and a #define Delete will not cause me problems in the future, because if it does, I change the define. I am an agile programmer and am simply looking for a technical solution to a specific problem.

Most of my C++ can actually go to Java
[/quote]

Yes, I saw this. That's primarily what made me conclude that you have no idea how to port software (or write C++, one or the other)

Best of luck to you, I'll butt out and let others try to help.
The problem is there is no real easy technical answer to The Problem because C++ and C# operate under fundimentally different memory models. The best you have, for compatibility, is the IDisposible interface to get some of the functionality back.

A concrete example might give concrete solutions, however none are likely to be language agnostic (as you seem to want) or do able via pre-processor hackery as they are likely to require extra levels of abstraction and 'manager' type classes to enable controlled clean up and release in keeping with the semantics of the language in question.

The simple fact is you do not write C# code like you write C++ code; doing so is just going to lead to shitty C# code and, more than likely, shitty C# performance.
Wait 1 year.
Download VS2011 (2012, whichever will launch).

Voila - your C++ code is now C# code. Or JS code. Or VB. Language simply doesn't matter anymore, if it's a library, it can be used from any language.

I dunno why "why" has to come up in a tech question with a tech answer, but here goes:


Because different languages and programming paradigms require you to approach problems differently. This is a tautology. What you have asked is how do to the same thing in two different languages without really explaining what that same thing is. You have claimed that you simply want to replicate object destruction, but it is clear that object destruction for you is more than just cleaning up resources, as you also seem to be handling reference counting in addition to resource destruction. Reference counting is usually not necessary in managed languages as once references to an object go out of scope, the resources that are used by the object are free to be released automatically. Of course there are exceptions to the rules, but that explains why people want more information concerning your approach and your needs.


I code in C++. I like C++. It can work on Windows, it can work on iOS, it can work on Linux, the only place it can't work is where Microsoft has decided thou shalt use C# and C# thou shalt use.
[/quote]

This is not even remotely true. The only time you need to use C# is when you want access to the .NET libraries, but this is hardly required for any project (although it is a valuable tool). And when working in .NET, you have access to multiple languages, not just C#. Perhaps much of your frustration is due to inexperience or a lack of education regarding the platform, and giving us more information concerning your problem will help us find the gaps in your knowledge to better arm you for the future?


I use very vanilla C++. I'm not a trickster with it. Most of my C++ can actually go to Java, even, with minimal changes. The only exception being destructors, which as I said above, I use heavily.
[/quote]

Here is the deal: Memory management in managed languages (Java, .NET, python, etc.) is a completely different paradigm from memory management in C++. Your issue seems to stem from a desire to try and equate the two. This is why we need more information: there is no easy answer to your problem because you are trying to do something that is fundamentally flawed.


I am trying to make my C++ delete my objects, while at the same time make it so that I can move the whole shebang over to C# if I should need to. I am working toward future compatibility. I am not using C# at this time.
[/quote]

In C++, you must manually delete heap allocated objects. In managed languages such as Java and C#, you do not need to manually delete heap allocated objects. Once all references to an object go out of scope, the memory allocated by that object is eligible to be "garbage collected" by the runtime. There is nothing the programmer needs to do to make this happen, other than ensure that they are no longer holding onto a reference to an object.

However, if your object is doing more than simply holding on to other managed objects (such as using an unmanaged resource) or requires additional logic at the time it is no longer needed by the application, then you must take additional steps. In C#, you have finalizers, which allow you to let go of unmanaged resources at the time the garbage collector decides to completely destroy your object. However, finalizers are non-deterministic, you never know when they will be invoked and you can never manually invoke them, because it is up to the garbage collector and the runtime. To compensate for this, .NET also uses the Dispose pattern. This allows for both deterministic deallocation of resources (by manually calling the dispose method or by implementing the using construct), and for non-deterministic resource deallocation, as if you forget to call dispose, it will be called by the garbage collector when it decides it can safely delete your object.


I am trying to give myself a consistent workaround, that I'll call all the time, to delete objects, which won't actually delete them on a managed language, but WILL invoke a "Destroy()" function that I can do housekeeping that I'd normally do in a destructor. I want this set up so I can use it fairly consistently in C++ and C# (small exceptions would be fine).
[/quote]

First of all, as we have already mentioned, trying to achieve parity between a managed and unmanaged language when it comes to memory management is a Bad Idea™. What I want to know is, what is the housekeeping you are doing in a destructor of your C++ objects that you need to do in C# that does not involve cleaning up allocated resources. This is the general purpose of destructors in C++, and if you are doing something else, you are not creating trivial destructors, so we need to know what makes your destructors so nontrivial. Your given example includes reference counting, but once again, we need to know what and why you are reference counting because this is often a process that is made unnecessary by managed languages.


For my own sanity, I want it compatible with arrays and other stuff, so that I have margin to be sloppy.

Now, I know the Array[] delete is possible... I have a solution above, but was wondering if a better one exists. The "call Destroy()" function thing I want is probably *not* possible, but I'm asking on the chance that someone has ever accomplished that.
[/quote]

You keep saying you want to delete objects, but at the same time you don't want to delete them. Can you see the fundamental disconnect here? What do you want Destroy() to do? Why do you want the object to continue living after calling Destroy()? Why can't you simply let the array fall out of scope or call Clear() on your List<>? What housekeeping do you need to do?


On the philosophy of programming: I know "change everything you're doing and do it my way" is always an option. But I am looking for a way to not "change everything I'm doing."
[/quote]

C++ and C# are miles apart as far as approach and paradigm. So are C++ and Java. There is no way you can #define your way into compatible solutions. If you are unwilling to adapt to the paradigms presented by your chosen tools, then all I can say is that you are Doing It Wrong™.

This topic is closed to new replies.

Advertisement