Can classes get by with the default constr/destructors? c++ - c++

Or do you have to manually create them? Was wondering if you can just create a class, declare some variables and method/functions. Then assign the object to your class in the int main function. Do you need to put in a constructor/deconstructor to create and destroy the memory that was used to hold to place of the variables or is there defaults that already do that?
Any additional info on constructors and destructors would be nice. Don't need a lot just some simple added info to make understanding this easier. Not trying to create programs that promote memory leakage

You do not need to explicitly provide a constructor/destructor as a default is generated for you. However, if you have any plain old data types, such as pointers to dynamically allocated memory, you will want to make certain that you provide your own manually specified destructor as the default will not be sufficient.

Related

Why use XXXX_new and XXXX_free over new and delete?

While reading into the libssh library, I saw that they specifically say
libssh follows the allocate-it-deallocate-it pattern. Each object that you allocate using xxxxx_new() must be deallocated using xxxxx_free()
Is this something that comes from it being a C library rather than a C++ library where new and delete didn't exist or is it a common practice to forget about new and delete and manually create and delete objects using the xxxx_new and xxxx_free pattern? If it is a common practice what are it's benefits over new and delete and the constructors and destructors that are called?
[EDIT] Added the link to where I read this as an <a> tag on "libssh library" for those asking.
A first glance at the link you provided reveals that libssh uses the xxxx_new() functions as combined allocator/constructor calls. It's really just a standard naming of factory functions. Likewise, xxxx_free() acts as a destructor/deallocator combination.
Combining allocation and construction into a single function call is a good idea whenever a library wants to provide typesafe opaque pointers to its user code: To compile the user code, the compiler only needs to know that the type exists and that it's distinct from any other type. There is no need to have the full class/struct declaration in a public header.
This approach is not very popular with C++ libraries, because they generally want their objects to behave like any normal C++ object (which means that the pointers/references must not be opaque to the compiler). But if a library provides a C interface, such factory functions make it unlikely that you get weird errors due to users passing in pointers to uninitialized objects (forgotten constructor call), or screwing up the allocation of your objects.
Is this something that comes from it being a C library rather than a C++ library where new and delete didn't exist
Most probably yes. There's often need for more initializations done than plain memory allocation as available with malloc() in c code. It's similar as new calls constructors of class/struct instances created.
or is it a common practice to forget about new and delete and manually create and delete objects using the xxxx_new and xxxx_free pattern?
No, that's not common practice in c++.
The way to deal with dynamically allocated instances and ownership is to use the functions and smart pointer classes from the standard c++ Dynamic memory management utilities.

How to create a destructor for a class

I see that for many classes the destructor is empty. However, this is not the case for all. Is there a rule on when we need to write something inside the destructor? If all our variables in the class are static, do we always just need an empty destructor?
You need a destructor when you need to do something when an item is destroyed. There is no standard thing you might need to do with a destructor.
Things you might choose to use a destructor for:
Terminate some running threads.
Provide a meaningful message to the user.
Print something important to a file, which will be lost after the item get deleted.
Deallocate memory using delete (memory which has been allocated using the new operator).
Close an internet connection socket.
While a destructor is an automated way of doing a job for each item, you might opt to do those tasks "manually", either in the main body of the program (not recommended) or by using specific methods for doing so.
If you don't define any constructor then c++ will create an empty default constructor for you.
So the answer is that you are free to decided whether to define or not to define an empty constructor. It doesn't make any difference in this case.
If all variables of class are static... It depends heavily on the situation but usually as a rule of thumb static classes don't use destructors because they are not instantiated like "normal" classes.
Sometimes it happens that you do need to have all variables in class static.
There is even a pattern for such situation. But this is more as an exception rather than a rule.

Is it safe to store a local declared object in a global QList?

I got a CPP program where i make a local object A and want to store it in global object B which is a QList.
Is it save to statically allocate object A or do i need to use the new keyword.
Does QList uses the copy constructor?
Thanks
QList stores copies of objects, so it should work. However make sure that copying is indeed what you want. If this isn't the case, allocate your object with new and store the pointer in the QList.
No. Inner scope variables should not be stored in outer scoped variables. You can store the values, but not the reference/pointer to that variable.
QList has only a pointer to it's contents. So whenever you make a copy of a QList it doesn't actually copy all of the contents, it just copies the pointer. Whenever you modify a list, a copy is made to ensure that it's not modifying the contents of other objects. See this: http://doc.qt.nokia.com/4.7-snapshot/qshareddatapointer.html
QList does use the copy contructor, so if your objects contain a lot of data, it might be not good to use straight objects in the QList, since copying can cause some overhead when the list needs to grow.
Another solution would be to use QSharedDataPointer to create functionality similar to that of the QList.
Note that most of Qt classes already use this, so if you class contains things listed here: http://doc.qt.nokia.com/4.7-snapshot/implicit-sharing.html It's somewhat unnecessary to use the QSharedDataPointer.
There is one thing that you didn't make clear that has of relevance, I think. Do you want the global static object A to have the same data as the object on the list?
This is achieveable by using either pointers or QExplicitlySharedDataPointer.
QExplicitlySharedDataPointer is much the same as QSharedDataPointer, with one exception.
It doesn't make a copy of the data when it's modified. Here's some documentation http://doc.qt.nokia.com/4.7-snapshot/qexplicitlyshareddatapointer.html
I'v used those classes a lot and I'v found them very useful and not hard at all to use.
nope. QList stores the list of pointers to objects, so local variables should not be stored in the global QList.
check out this link for details:
http://twl.pl/jtz/Inne/QT-Tutorial/qlist.html#details

Why do I need to call new? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
When to use “new” and when not to, in C++?
When should I use the new keyword in C++?
It seems like I could program something without ever using the word new, and I would never have to worry about deleting anything either, so why should I ever call it?
From what I understand, it's because I would run out of stack memory.
Is this correct? I guess my main question is, when should I call new?
It's a matter of object lifetime: if you stack-allocate your objects, the objects destructors will be called when these objects go out of scope (say, at the end of the method). This means that if you pass these objects out of the method that created them, you'll find yourself with pointers to memory that could be overwritten at any time.
It's because you may not know at compile time whether you need an object, or how many, or of what type. The new operator allows you to dynamically allocate objects without having to know such things in advance.
Here's an example of not knowing the type of object in advance:
class Account { ... };
class CheckingAccount : public Account { ... };
class VisaAccount : public Account { ... };
...
Account *acct = type == "checking" ? new CheckingAccount : new VisaAccount;
The main reason you'll need to use new/delete is to get manual control the lifetime of your objects.
Other reasons are already provided by others but I think it's the more important. Using the stack, you know exatly the lifetime of your objects. But if you want an object to be destroyed only after an event occurs, then it cannot be automatically defined.
The lifetime of the data/objects created on the stack is restricted to the block. You cannot return references/pointers to it. For data to be available across functions, you can create it on the heap with new. Of course, it can be at a higher level, or even global. But you seldom know at compile time how much data/how many objects will be needed at run time.
You can write a many non-trivial programs without ever calling "new." (or thus delete).
What you wouldn't be able to do (at least without writing or using your own equivalents) is decide what type of objects or how many you want to create at run-time, so you'd be limiting yourslef.
[updated]
You can use new to create new instance of some class, or allocate memory (for array for example), like
Object o = new Object();
Before creating new instance of class Object, you cannot use it. (Unless you have static methods.)(this is just one example of usage, sometimes other objects will instantiate or destroy objects that you need/don't need)
There are many good answers here but it is difficult to explain everything about new in one reply on SO, and if you do not understand what happens when new is called then it is difficult to know when to use it. This is one of the most important areas in programming so, after reading basic information here you should study it in more detail. Here is one of possible articles where you could start your research:
http://en.wikipedia.org/wiki/New_%28C%2B%2B%29
Topics that you will have to learn in order to understand what happens when you call new, so that you then could understand when to call it (there are more probably but this is what i can think of now):
- constructors (and destructors)
- static classes and methods
...

Static Pointer to Dynamically allocated array

So the question is relatively straight forward, I have several semi-large lookup tables ~500kb a piece. Now these exact same tables are used by several class instantiations (maybe lots), with this in mind I don't want to store the same tables in each class. So I can either dump the entire tables onto the stack as 'static' members, or I can have 'static' pointers to these tables. In either case the constructor for the class will check whether they are initialized and do so if not. However, my question is, if I choose the static pointers to the tables (so as not to abuse the stack space) what is a good method for appropriately cleaning these up.
Also note that I have considered using boost::share_ptr, but opted not to, this is a very small project and I am not looking to add any dependencies.
Thanks
Static members will never be allocated on the stack. When you declare them (which of course, you do explicitly), they're assigned space somewhere (a data segment?).
If it makes sense that the lookup tables are members of the class, then make them static members!
When a class is instanced on the stack, the static member variables don't form part of the stack cost.
If, for instance, you want:
class MyClass {
...
static int LookUpTable[LARGENUM];
};
int MyClass:LookUpTable[LARGENUM];
When you instance MyClass on the stack, MyClass:LookUpTable points to the object that you've explicitly allocated on the last line of the codesample above. Best of all, there's no need to deallocate it, since it's essentially a global variable; it can't leak, since it's not on the heap.
If you don't free the memory for the tables at all, then when your program exits the OS will automatically throw away all memory allocated by your application. This is an appropriate strategy for handling memory that is allocated only once by your application.
Leaving the memory alone can actually improve performance too, because you won't waste time on shutdown trying to explicitly free everything and therefore possibly force a page in for all the memory you allocated. Just let the OS do it when you exit.
If these are lookup tables, the easiest solution is just to use std::vector:
class SomeClass {
/* ... */
static std::vector<element_type> static_data;
};
To initialize, you can do:
static_data.resize(numberOfElements);
// now initialize the contents
With this you can still do array-like access, as in:
SomeClass::static_data[42].foo();
And with any decent compiler, this should be as fast as a pointer to a native array.
Why don't you create a singleton class that manages the lookup tables? As it seems they need to be accessed by a number of classes; make the singleton the manager of the lookup tables accessible at global scope. Then all the classes can use the singleton getters/setters to manipulate the lookup tables. There are 3 advantages to this approach:-
If the static container size for the
lookup tables becomes large then the
default stack-size may ( 1MB on
Windows) lead to stack-overflow on
application statrt-up itself. Use a container that allocates dynamically.
If you plan to access the table via multiple-threads, the singleton class can be extended to accompany locked access.
You can also cleanup in the dtor of singleton during application exit.
I can think of several ways to approach for this depending upon what is trying to be accomplished.
If the data is static and fixed, using a static array which is global and initialized within the code would be a good approach. Everything is contained in the code and loaded when the program is started so it is available. Then all of the class which need access can access the information.
If the data is not static and needs to read in, an static STL structure, such as a vector, list or map would be good as it can grow as you add elements to the list. Some of these class provides lookup methods as well. Depending upon the data you are looking up, you may have to provide a structure and some operator to have the STL structures work correctly.
In either of the two case, you might what to make a static global class to read and contain the data. It can take care of managing initialization and access the data. You can use private members to indicate if the class has been read in and is available for use. If it has not, the class might be able to do the initialization by itself if it has enough information. The other class can call static function of the static global class to access the data. This provides encapsulation of the data, and then it can be used by several different classes without those classes needing to incorperate the large lookup table.
There are several possibilties with various advantages and disadvantages. I don't know what the table contains, so I'll call it an Entry.
If you just want the memory to be sure to go away when the program exits, use a global auto_ptr:
auto_ptr<Entry> pTable;
You can initialize it whenever you like, and it will automatically be deleted when the program exits. Unfortunately, it will pollute the global namespace.
It sounds like you are using the same table within multiple instances of the same class. In this case, it is usual to make it a static pointer of that class:
class MyClass {
...
protected:
static auto_ptr<Entry> pTable;
};
If you want it to be accessible in instances of different classes, then you might make it a static member of a function, these will also be deleted when the program exits, but the really nice thing is that it won't be initialized until the function is entered. I.e., the resource won't need to be allocated if the function is never called upon:
Entry* getTable() {
static auto_ptr<Entry> pTable = new Entry[ gNumEntries ];
return pTable;
}
You can do any of these with std::vector<Entry> rather than auto_ptr<Entry>, if you prefer, but the main advantage of that is that it can more easily be dynamically resized. That might not be something you value.