Delete C++ Class Unreal

0 views
Skip to first unread message

Gualtar Pennington

unread,
Aug 5, 2024, 12:38:48 PM8/5/24
to podsventohas
Idid find a solution from the internet that says to delete the source file for it and then delete the binaries folder. I did that and then unreal asks to build the project and the build always fails.

The above steps work for me as well, however, to delete the class from the Content Browser as well, I had to clean and rebuild my project after step 5 as well (which rebuilds the entire engine unfortunately).


The class still being present in the Content Browser after following the steps listed by C may not be correct. If you have not already done so, could you please create a new post regarding that issue so we can track and investigate it?


I just realized that I should probably clarify something that might be obvious to some users, but perhaps not to everyone who may read this post. After deleting the Binaries and Intermediate folders, you would need to generate project files before opening the solution in Visual Studio and building the project again.


Now because there is an intermediate folder where some more build tool magic happends I generally perform a clean which ungunks any left over artifacts of the file I just deleted (you can also just delete the intermediate folder). Finally a fresh build (as long as all my references are gone) finishes the job by rebuilding the intermediate folder and generating my dlls.


Just a real quick question for you. Did you delete ALL of the .cpp and .h files from your source folder? Assuming you started with a Blueprint project that you added a custom component class to, you should still have a .h and .cpp file in the source folder that have the same name as your project.


Trying to delete a c++ class (this should not be this difficult!) and I have deleted the .h, .cpp, and binaries. Next everybody says "now, right click on your .uproject file and select Generate Visual Studio files." Where do i right click it? I can't find the file in Visual Studio, and it doesn't give the option to generate the files in my file browser. Sorry about the noob question, but I 've google searched to no avail. thnx.


I was in the process of migrating some new Apex into our Production Org and this old completed unrelated Test Class kept on throwing an error. So after several hours, I was able to delete this unrelated Test Class from the Production Org. The original code that it's testing is still intact. Is there anything I should watch out for because of this?


Deleting the test classes from the production will bring down the code coverage.More specifically, if your environment has changed to the point that your old test classes are not functioning, those test classes should be updated OR the code they are referencing should be removed.


This delete seems like a very low price to pay for non-freezing environment. Placing all relevant delete keywords is a mechanical task. One can write a script that would travel through the code and place delete once no new branches use a given object.


I don't want to start a C++ vs Java thread. My question is different.

This whole GC thing - does it boil down to "just be neat, don't forget to delete objects you have created - and you will not need any dedicated GC? Or is it more like "disposing objects in C++ is really tricky - I spend 20% of my time on it and yet, memory leaks are a common place"?


If you use object pointers and create objects on the free store, then you have to take care of deleting the object when it's no longer needed (as you have described). Unfortunately, in complex software this might be much more challenging than it looks like (e.g. what if an exception is raised and the expected delete part is never reached ?).


Fortunately, in modern C++ (aka C++11 and later), you have smart pointers, such as for example shared_ptr. They reference-count the created object in a very efficient manner, a little bit like a garbage collector would do in Java. And as soon as the object is no longer referenced, the last active shared_ptr deletes the object for you. Automatically. Like garbage collector, but one object at a time and without delay (Ok: you need some extra care and weak_ptr to cope with circular references).


The nice thing is that you don't have to worry about object lifecycle. You just create them and java takes care of the rest. A modern GC will identify and destroy the objects that are no longer needed (including if there are circular references between dead objects).


This is perfectly fine if looking at objects only in terms of memory. Except for the freeze, but these are not a fatality (people are working on this). I'm not Java expert, but I think that the delayed destruction makes it more difficult to identify leaking in java due to references accidentally kept despite objects are no longer needed (i.e. you can't really monitor the deletion of objects).


But what if the object has to control other resources than memory, for example an open file, a semaphore, a system service ? Your class must provide a method to release these resources. And you'll have the responsibility to make sure that this method is called when the resources are no longer needed. In every possible branching path through your code, ensuring it is also invoked in case of exceptions. The challenge is very similar the explicit deletion in C++.


Conclusion: the GC solves a memory management issue. But it doesn't address the the management of other system resources. The absence of "just-in-time" deletion might make resource management very challenging.


When you can control the deletion of an object and the the destructor that is to be invoked at deletion, you can take benefit of the RAII. This approach views memory only as a special case of resource allocation and links resource management more safely to the object life cycle, thus ensuring tightly controlled usage of resources.


The only way you can actually avoid memory leaks in practical cases is very strict coding standards with very strict rules who is the owner of an object, and when it can and must be released, or tools like smart pointers that count references to objects and delete objects when the last reference is gone.


Making programmers' lives easier and preventing memory leaks is an important advantage of garbage collection but it's not an only one. Another is preventing memory fragmentation. In C++, once you allocate an object using the new keyword, it stays in a fixed position in memory. This means that, as the application runs, you end up having gaps of free memory in between allocated objects. So allocating memory in C++ must by necessity be a more complicated process, as the operating system needs to be able to find unallocated blocks of given size that fit between the gaps.


Garbage collection takes care of it by taking all objects that aren't deleted and shifting them in memory so that they form a continuous block. If you experience that garbage collection takes some time, that's probably because of this process, not due to memory deallocation itself. The benefit of it is that when it comes to memory allocation, it's almost as straightforward as shifting a pointer to the end of the stack.


Seems like Java guarantees you that garbage will be disposed (not necessarily in an efficient way). If you use C/C++ you have both freedom and responsibility. You can do it better than Java's GC, or you can be much worse (skip delete all together and have memory leak issues).


If you need code that "meets certain quality standards" and to optimize "price/quality ratio" use Java. If you are ready to invest extra resources (time of your experts) to improve performance of mission critical application - use C.


In Java, this is exception safe, because all we're really doing is copying a reference to an object, which is guaranteed to happen without an exception. The same is not true in C++ though. In C++, returning a value means (or at least can mean) copying that value, and with some types that could throw an exception. If the exception is thrown after the item has been removed from the stack, but before the copy gets to the receiver, the item has leaked. To preven that, C++'s stack uses a somewhat clumsier approach where retrieving the top item and removing the top item are two separate operations:


The same is true in many other parts of C++: especially in generic code, exception safety pervades many parts of design--and this is due in large part to the fact that most at least potentially involve copying objects (which might throw), where Java would just create new references to existing objects (which can't throw, so we don't have to worry about exceptions).


As far as a simple script to insert delete where needed: if you can statically determine when to delete items based on the structure of the source code, it probably shouldn't have been using new and delete in the first place.


Let me give you an example of a program for which this almost certainly wouldn't be possible: a system for placing, tracking, billing (etc.) phone calls. When you dial your phone, it creates a "call" object. The call object keeps track of who you called, how long you talk to them, etc., to add appropriate records to the billing logs. The call object monitors the hardware status, so when you hang up, it destroys itself (using the widely discussed delete this;). Only, it's not really as trivial as "when you hang up". For example, you might initiate a conference call, connect two people, and hang up--but the call continues between those two parties even after you hang up (but the billing may change).


Something that I don't think has been mentioned here is that there are efficiencies that come from garbage collection. In the most commonly used Java collectors, the main place that objects are allocated is an area reserved for a copying collector. When things start, this space is empty. As objects are created, they are allocated next to each other in the big open space until it can't allocate one in the remaining contiguous space. The GC kicks in and looks for any objects in this space that are not dead. It copies the live objects to another area and puts them together (i.e. no fragmentation.) The old space is considered clean. It then continues allocating objects tightly together and repeats this process as needed.

3a8082e126
Reply all
Reply to author
Forward
0 new messages