I dont understand the point of constructors in C++?

I have a record of over complicating concepts, and Im sure Im doing the same in this part too. I dont understand why constructors are used, Ive been told it's not even needed in todays compilers but I see people using them all the time? I've read the tutorials on this site and still nada. Can someone explain to me how they work in the easiest way possible and what's the point of them? Thanks in advance!
Last edited on
Ive been told it's not even needed in todays compilers


This is false. Either you misunderstood what that person was saying, or they didn't know what they were talking about.

Can someone explain to me how they work in the easiest way possible and what's the point of them?



They let you ensure that your object is always in a known state by being called as soon as the object is first created.

For example, take this simple code:

1
2
3
string mystring;  // constructor called here

cout << mystring;


string is a class that uses a constructor. That constructor does a few things:

-) It [possibly] allocates memory for the string data.
-) It makes sure the string is "empty"
-) It set other "internal use" things, like sets the capacity, length, etc so all of it is at a known state.

The above cout line will always output nothing (an empty string) because strings are "constructed" to a known state.

On the other hand, basic types like char have no constructor, so:

1
2
3
char boogie[10];  // no constructor for char

cout << boogie;


This code might print nothing. Or it might print random garbage. There's no way to know because boogie was never constructed to a known state.

The printed data might even spill out passed the end of the 'boogie' buffer, potentially crashing the program via an access violation!


So yeah, basically constructors initialize the class. Since they're called automatically, this means you never have an object that hasn't been initilized, which means it's harder to misuse classes.
Objects are abstract ways for programmers to look at data structures (and how to handle them) or objects as they exist in reality. The data members that are associated with these objects (like all other data) need initialization. Whenever a new instance of a class is made, you can automate this progress, by using a constructor. Let's say we have the following:
1
2
3
4
5
6
7
8
9
10
class MyClass
{
private:
      int MyDataMember;
public:
      MyClass()
      {
            MyDataMember = 0;
      }
}

This means that whenever we create an instance of the class MyClass, it "automatically" gets the value 0.

When you understand this basic concept. Try learning about copy constructors, constructors that take parameters in general, initializer lists, defining them outside of the class, destructors and so on.
The point is to reserve(construct) a memory same as for a single variable but for many at a time.
Optionally to reload it after.
Without them one is never sure what class memory holder is being under reloading.
By default they are not inherited as well as destructors.

hope it helps
So it's used to sort of tell the compiler that there IS a class in the file? My tutor told me that c++ already knows that though? In short, it's sort of like declaring a class?

And you always need it? What's going to happen if you don't use it? Because before I found out about these, I was still using classes and they were still working just fine?

And another thing, do you need to put in all the variables you used in the class?

EverBeginner: What do you mean reloading? So without a constructor, I can't use a class more then once of something?
Last edited on
I don't understand very well what EverBeginner meant, but memory is reserved whenever an object of a given type is declared. It has nothing to do with constructors. You use constructors to help initialize that memory. Typically, a default constructor will set data members to a reasonable "empty" state, while constructors that take arguments will use them to initialize the proper members. You don't need to mention every member in a constructor, although it's very recommended that you never leave data uninitialized.
Soap360 wrote:
So it's used to sort of tell the compiler that there IS a class in the file? ... In short, it's sort of like declaring a class?


No. Not at all.

And you always need it?


No. You only need it if your class needs to be initialized in some special way.

And another thing, do you need to put in all the variables you used in the class?


I don't understand this question. Can you clarify?




Anyway regarding the constructor... let's keep this in simple terms:

A constructor is just a function.

The thing that makes it special is it's called automatically when an object is created. This let's you put in any initialization code that you want to be performed whenever the class is used. This makes it impossible (or at least harder) for people to misuse classes by forgetting to initialize them, because the initalization is done automatically.

So instead of doing this:

1
2
MyClass foo;  // create an object
foo.Initialize();  // initialize it so that everything is set up and ready to go 


you can just do this:

1
2
MyClass foo;  // create an object -- but this also automatically calls the ctor
  // which initializes it so everything is ready to go 
Last edited on
So without a constructor, I can't use a class


Hello Soap360,

Yes, you can't unless the c++ inheritence feature is used by your software.
Take on account 1000 variables that is far less than required by a distributable program
to at least hundreds users with numerous tastes. You would need that much of constructors.
Also destructors rewriting these variables on each declaration.
All a constructor for a user-defined type does is allow you, the creator of the user defined type, to initialize the members of the object to some sane values at the point of instantiation of the object rather than on a separate line of code, which is what Disch's last two examples demonstrate.

EverBeginner wrote:
Yes, you can't unless the c++ inheritence feature is used by your software.


This is not true, and doesn't even really make sense.

I don't normally like to discourage people who are trying to help... but please stop EverBeginner. I fear you are just confusing Soap and are spreading false information.
Yeah, I don't really know what's he talking about either, no offense EverBeginner

So I guess Im starting to understand why it's used.. but the reason Im sort of pushing away from them is because, like I mentioned, I've been using classes many many times without using a constructor, and it seems so unnecessary. So my final post is this:

1. When do you NEED to use constructors/is it optional, is it a necessity?

2. How do they help your code/program/etc.

3. Is it a problem when you don't use them?

4. Examples?

Like I mentioned before, I've used classes many many many times without constructors and things turned out fine. So I guess Im sorta not used to it? Maybe it's a big concept that I missed out on... I dont know. If it's really important please let me know.

I'd just like to thank all of you for guys for your help. I really appreciate your time and effort.

Regards,

Soap360
Last edited on
I hope it's not your final post. =(

Anyway, I thought I answered this already... but okay... I'll try to explain a little further.

1) Strictly speaking, you never need them. But you do need them if you want a properly encapsulated class.

2) They help make your classes encapsulated.

3) It's only a problem if you're trying to make encapsulated classes


Encapsulation can be a difficult concept to grasp. Basically to be encapsulated means to be "self contained" and "self managing". A class that is properly encapsulated will be next to impossible to misuse in disasterous fashions.

4)
Here's a simple example of a class that acts as an array of 50 integers.

Here's a class that is properly encapsulated:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Array50
{
private:
  int* data;

  // you can ignore these next two lines, they just make it so this class can't be copied:
  //  while somewhat unimportant to this example, this wouldn't be a properly encapsulated
  //  class without them... so I felt I had to include them
  Array50(const Array50&);
  Array50& operator = (const Array50&);

public:
  Array50()  // the constructor
  {
    data = new int[50];  // allocate memory for the array
  }

  ~Array50()  // the destructor
  {
    delete[] data;  // free the memory for the array
  }

  // overloading the [] operator:
  int& operator [] (int index)
  {
    return data[index];
  }
};


Because this class is encapsulated... using it is a breeze:

1
2
3
4
5
6
void somefunction()
{
  Array50 myarray;  // constructor automatically called, memory allocated

  myarray[12] = 34;  // this is OK
}  // destructor automatically called, memory deleted.  No worry about memory leaks. 


Here's a simpler, somewhat encapsulated class, but doesn't use ctors or dtors to properly encapsulate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Array20
{
private:
  int* data;

public:
  void Init()
  {
    data = new int[20];
  }

  void Destroy()
  {
    delete[] data;
  }

  int& operator [] (int index)
  {
    return data[index];
  }
};


Now, using this class is no longer cut and dry. Here's how you'd use the class properly:

1
2
3
4
5
6
7
8
9
10
void somefunction()
{
  Array20 myarray;

  myarray.Init();  //allocate the memory

  myarray[12] = 34;  // OK

  myarray.Destroy();  // clean up
}


Note the allocation and cleanup are no longer automatic. You have to remember to do it every time you use the class. Because of that, it's very easy to misuse the class and have disasterous results:

1
2
3
4
5
6
7
8
9
10
void mybadcode()
{
  Array20 a;
  a[12] = 34;  // BAD, heap corruption.  Accessing memory via an uninitialized pointer
  a.Destroy();  // BAD, deleting memory that was never allocated

  Array20 b;
  b.Init();  // OK
  b.Init();  // BAD, memory leak.  memory allocated in first call to init was never deleted, resulting in leak
}  // BAD, another memory leak.  2nd call to Init was never properly deleted 




Can you imagine if you had to manually prepare and cleanup after classes like string, vector, list, etc? They would be very difficult to use! All of those STL classes use constructors and destructors to properly maintain their data so that the person using the class doesn't have to worry about it.

Encapsulated classes "just work", and are actually somewhat difficult to use improperly.. And if the classes just work, then it's much, MUCH easier to write code using those classes.
Last edited on
Wow, thanks Disch. I understood the concepts but your examples really help clarify things. Kudos!
That's probably the best answer I've ever recieved on a forum. Wow, if I knew you I'd send you a bottle of liquor or something :D I fully understand it now, I can't thank you enough. Thanks sooo much! :D
^^

Glad to help.
Topic archived. No new replies allowed.