Sign in to follow this  
bluefox25

? about the default constructor

Recommended Posts

I hate having to start a thread for just for one simple ?. Wish there was an ongoing thread where you can ask newbie questions, oh well, here goes: A)When defining a default constructor I know it is legal to do this: Class::Class():mVar1(something),mVar2(something){} B)If there is nothing else but is this still legal Class::Class():mVar1(something),mVar2(something){ cout << "Some cool statement..."; } C)or would I need to do this: Class::Class(){ cout << "Some cool text"; mVar1(something); mVar2(something); } Not quite sure. My first guess would be B but I've been wrong before :(

Share this post


Link to post
Share on other sites
Quote:
Original post by bluefox25
B)If there is nothing else but is this still legal
Class::Class():mVar1(something),mVar2(something){
cout << "Some cool statement...";
}

Yes. This calls mVar1 and mVar2's constructors.

Quote:
C)or would I need to do this:
Class::Class(){
cout << "Some cool text";
mVar1(something);
mVar2(something);
}

No. This would call mVar1 and mVar2's operator(), assuming they had appropriate ones, which is entirely different.

Share this post


Link to post
Share on other sites
So when defining the default constructor, you need to always place the member variable assignments before the {}?
Class::Class():mVariablex(){}
I thought it was only to save space that you could writ it like that.

Share this post


Link to post
Share on other sites
Quote:
Original post by bluefox25
So when defining the default constructor, you need to always place the member variable assignments before the {}?


No. Member variable assignments must be placed inside the constructor body, and they use operator = anyway. The list placed before the body is called the initializer list, and it contains the initializations of the members.

Note that members are always initialized, so the initializer list only helps you specify which constructor they are initialized with (in place of their default constructor).



Share this post


Link to post
Share on other sites
Quote:
Original post by bluefox25
So when defining the default constructor, you need to always place the member variable assignments initializers before the {}?

Yes (for the fixed terminology -- although you can omit any initializations where you're fine with just the default, as they will, well, default :D). (Assignment uses '=', and is a bit different if the class does anything fancy -- usually just potentially a bit more expensive).



Quote:
I thought it was only to save space that you could writ it like that.

If B and C were equivilant, there wouldn't be a space saving:
Class::Class():mVariablex(){}
Class::Class(){mVariablex();}


See?

Share this post


Link to post
Share on other sites
Sorry that is what I meant, initialization, so whatever I place before the braces, will be the default value for the member variables, unless I assign a value to those member values:
If I have:

Class axis{
int x;
int yl
axis();
}
Class::axis():x(5),y(4){}//set/initialize member variables
//So if I declar:
axis myAxis;//This will set x(5) & y(4) right?
//unless I specify values like this:
axis myAxis(10,25);



Is this correct ?

Share this post


Link to post
Share on other sites
Given

Class axis{
int x;
int yl
axis();
}
Class::axis():x(5),y(4){}//set/initialize member variables
//So if I declar:
axis myAxis;//This will set x(5) & y(4) right?

you are correct that x and y is set to 5 and 4, respectively. The default constructor will initialize the member to those values. However,

//unless I specify values like this:
axis myAxis(10,25);

is not correct. Since you only provided a default constructor, you cannot initialize the object with a non-default constructor. You haven't provided a contructor taking any parameters. So the last one is invalid code.

Share this post


Link to post
Share on other sites
Ahhh, now I see. That is why including a constructor with parameters is needed. If I added another constructor like:

Class axis{
public:
axis();//default constructor
axis(int a,int b);//condstructor
private:
int mx;
int my;
}
axis::axis():x(5),y(4){}//set/initialize member variables
axis:axis(int a,int b){ // sets constructor
mx = a;
my = b;
}


How many constructors can you have in any given clas? No limits?

Share this post


Link to post
Share on other sites
I just read that there is also a thing called a copy constructor. Something about how it calls an object and copies it?

How is this different from a constructor? Is it implemented in the same way, how would you call the copy constructor(assuming it is defined)?

Share this post


Link to post
Share on other sites
Quote:
Original post by bluefox25
I just read that there is also a thing called a copy constructor. Something about how it calls an object and copies it?

How is this different from a constructor? Is it implemented in the same way, how would you call the copy constructor(assuming it is defined)?


Search The ****ing Web!
[ google | imageshack ]

Share this post


Link to post
Share on other sites
Would I need to define a constructor differently if I were using pointers? Suppose I had cstring variables that the pointer pointed to, would it be something like this:

typedef char* charString;
Class axis{
public:

axis();//default constructor
axis(charString a,charString b);//condstructor
private:
charString mx;
charString my;
}
axis::axis():mx("Hi"),my("Mom!"){}//set/initialize member variables

axis:axis(charString a,charString b){ // sets constructor for two parameters
strncpy(mx,a);
strncpy(my,b);
}




Would this work? I do not know if I setup the strncpy function, need to look it up!! :)

Share this post


Link to post
Share on other sites
Quote:
Original post by bluefox25
Would this work? I do not know if I setup the strncpy function, need to look it up!! :)


It wouldn't. You need to initialize pointers before using strncpy on them. Although this was just an example, remember you can use std::string intuitively [wink]

Share this post


Link to post
Share on other sites
Quote:
Original post by bluefox25
Would I need to define a constructor differently if I were using pointers? Suppose I had cstring variables that the pointer pointed to, would it be something like this:
*** Source Snippet Removed ***

Would this work? I do not know if I setup the strncpy function, need to look it up!! :)


Nope. The problem is that you aren't using std::string to represent text. More specifically, the pointers mx and my don't point anywhere in particular, so using them results in undefined behaviour. This could be anything, but if you are lucky your program will crash. I say lucky because then at least you know there is a problem. If it doesn't crash it means you are using memory that typically belongs to another part of your program, for instance another variable! So by creating an instance of "axis" the values of other variables change. Have fun tracking that one down [smile]

Also, if you chose not to use std::string (which you aren't going to do, right?) then you will have to allocate some space with new[]. This will introduce you to the constructors close relative, the destructor, where you get to clean up after yourself.

Share this post


Link to post
Share on other sites
The quicker picker upper.......Destructor!!
Somehow that doesn't sound good

but yes I kind of figured that I would need to define the destructor. So do I need to create a dynamic aray within the definition for the two parameter contructor.
like this:

.........
axis::axis(charString a,charString b){ // sets constructor for two parameters
a = new char;
b= new char;
mx= new char;
my = new char;
strncpy(mx,a);
strncpy(my,b);
}


Is this kind of what I need to do? I am still trying to learn about pointers and allocating memory.

Share this post


Link to post
Share on other sites
Quote:
Original post by bluefox25
The quicker picker upper.......Destructor!!
Somehow that doesn't sound good

but yes I kind of figured that I would need to define the destructor. So do I need to create a dynamic aray within the definition for the two parameter contructor.
like this:
*** Source Snippet Removed ***
Is this kind of what I need to do? I am still trying to learn about pointers and allocating memory.


Not quite. If you haven't used pointers much I'd concentrate on getting constructors down first.

As for destructors, they are like constructors in many ways except they are called when an object is being, well, destroyed rather than when objects are about to come into existance.

The code you gave had a couple of errors.

0) you assigned to the parameters. Technically this is not an error but it will have unintended consequences for you.

1) you only allocate a single character when you write "new char". A string typically holds quite a few characters, so that isn't going to work either. To allocate a number of characters at once, we use new char[N], for example, to get 7 chars: new char[7].

2) every time you use new, you have to remember to "clean up" using delete. When you use new[], you have to use delete []. Note, you dont use a number for delete, just write delete [] somePointer, not delete [7] somePointer;

3) C strings are horrible nasty things. They must always end in a special character, '\0', the NUL character ( different from NULL pointers ). As such if you want a string with 10 characters in it, you need room for 11 and you need to remeber to put a '\0' character at the end (unless you are using a function that doesn that for you)

I will not provide code to demonstrate how to handle manual memory management like this, as it is quite involved and may be beyond your grasp just yet. Typically such a class will need a carefully written constructor, destructor, copy constructor and overloaded operator=(), which you probably have not encountered yet.

Of course, using std::string I can rewrite your example quickly:

#include <string>

typedef char* charString;
Class axis{
public:

axis();//default constructor
axis(charString a,charString b);//condstructor
private:
std::string mx;
std::string my;
}
axis::axis():mx("Hi"),my("Mom!"){}//set/initialize member variables

axis:axis(charString a,charString b):mx(a),my(b){ // sets constructor for two parameters
}

Share this post


Link to post
Share on other sites
Quote:
Original post by bluefox25
Couldn't Ise the memcpy function?
*** Source Snippet Removed ***

You could, but to what gain?

That's half the battle. The other half is ensuring that the pointers always point to enough space, to valid space, yet never leak memory. The std::string class is designed to do all that for you.

If you want to look at example code for the manual version, here you go( untested):

// std::copy lives here I think
#include <algorithm>

typedef char* charString;

class axis{
public:

axis();//default constructor
axis(charString a,charString b);
// a destructor never takes any arguments
// and is the class name prefixed with a tilde ~
~axis();
private:

// these 2 lines prevent people creating
// accidental "copies" of axis objects
// without these our class runs the risk of leaking memory
// dont worry too much if you don't understand these
axis( const axis & );
axis &operator=( const axis & );

charString mx;
charString my;
}

// to maintain the class invariants, we must ensure that
// the member pointers point to something we have allocated
// so we can deallocate them later
//
// std::copy is the c++ way of copying stuff
// it calls the correct constructors, unlike c's memcpy()
// in tat way it can work with any type
axis::axis()
{
const char *hi = "Hi", mom = "Mom";
int hiLen = strlen(hi) + 1;
int momLen = strlen(mom) + 1;
mx = new char[hiLen];
std::copy(hi, hi + hiLen + 1, mx );
my = new char[momLen];
std::copy(mom, mom + momLen + 1, my );
}

axis:axis(charString a,charString b){
int aLen = strlen(a) + 1;
int bLen = strlen(b) + 1;
mx = new char[aLen];
std::copy(a, a + aLen + 1, mx );
my = new char[bLen];
std::copy(b, b + bLen + 1, my );
}

axis::~axis() {
// release the resources
delete [] mx;
delete [] my;
}




See how complicated the code has become? Our class now has invariants that have nothing to do with the purpose of the class. We can no longer make copes of our class intuitively like we could with the std::string version. We have to ensure the mx and my pointers point to valid heap memory (so delete [] will work) and we have to be very careful later on when we decide we need to be able to modify the member strings contents.

Were we to attempt to concatenate to one of the member strings, our current method requires that we attempt to allocate a bigger string, perform a copy and then release the old one. Anything more and we would be re-implementing std::string while gaining none of its time tested code.

Don't worry about strcpy and memcpy. Most times you see this kind of thing is in C code (where std::string doesn't exist [crying] ) or in really, really bad c++ code.

Discussion of memory management etc really belongs to a question of its own, but it is tied to constructors as that is how C++ takes some of the pain associated with manual memory management away. As an example look at the std::string version of our class. Even though std::string has numerous constructors, and proper implementations of destructors and copy operations, we can use it naturally and it will just work(tm). We dont even need to write such things for our class, as C++ will generate a copy-constructor, operator= and default (no-argument) constructor for you which will work just fine most of the time.

Share this post


Link to post
Share on other sites
That makes sense in a mixed up kind of way!! I did not think about searching inside the String class for functions. I looked under the cstring library because we are dealing with cstrings. I have alot to learn!!!

Thanks

Share this post


Link to post
Share on other sites
I think I have been studying too hard!! I am all confused on pointers in terms of how to pass them as parameters!!

I am even surprised that I cn remember what a pointer is!!
Would it be ok to initialize the default contructor as:

Student::Student(){
mx = new char[10];
mName = "Hi";
my = new char[10];
my = "Mom!!";
cout << "Student() - Default Constructor\n";
}


Assuming I use the destructor as defined in the other post.........

Share this post


Link to post
Share on other sites
This stuff can be tough. They just threw all of these things at us w/o really explaining how they work. The chapter includes pointers,dynamic arrays, default constructors,constructors,copy constructors,destructors and structs and classes at uss!!
They do all go together but its a bit much for a week's worth of reading/homework.

Our assignment must use cstrings, however is creating a pointer to char, a cstring? or does it become a cstring upon creating a dynamic variable which then becomes a dynamic array?

typedef char* ptr;
ptr = new char;//a single char
ptr = new char[]//What size would you use?

It is slowly coming together......slowly....lol.

Please tell me I am not the only one who has struggled to coonect the dots with the various concepts at any given time??

I know I can't be that dumb!! I just have to constantly refer to reference books, can't remember every function in every library!!

My rant is over........for now..

Share this post


Link to post
Share on other sites
Quote:
Original post by bluefox25
Our assignment must use cstrings, however is creating a pointer to char, a cstring? or does it become a cstring upon creating a dynamic variable which then becomes a dynamic array?


The difference isn't a technical one, really. A char array (not a pointer-to-char; this is merely what the array decays to when passed) is just that -- an array of chars. This is often used to store strings (which is a bad thing in C++, unless you're writing your own string class to encapsulate this -- which you should only do if you have a reason) but it can also be used to simply store an array of completely unrelated chars. It becomes a cstring when you attribute this term to it. Kind of like how a hammer is really just a tool; but if you use it to hit someone with, then it becomes a weapon.

Quote:
typedef char* ptr;
ptr = new char;//a single char
ptr = new char[]//What size would you use?


This is one of the primary problems with char-arrays-as-strings -- you do not know what size of input the user will give you, and you must allocate enough space in advance. You have to increase the space allocation as necessary yourself -- which is messy, to say the least. You can simply say 'ah, this'll be enough' and allocate something like 64kB of space -- but then a malicious user (or simply something seriously awry elsewhere) might enter more data than that in order to execute arbitrary code (a buffer overflow).

Quote:
Please tell me I am not the only one who has struggled to coonect the dots with the various concepts at any given time??


You're definitely not. It's difficult to come up with any reasonable order to teach things in, because one you're past the completely trivial things, they all inter-relate in different ways. This is, IMHO, one of the reasons that there are so few decent books teaching programming (that, and the fact that people that know little more than I do profess to be experts and then publicize their knowledge when in fact there are holes or problems with it).

Quote:
I know I can't be that dumb!! I just have to constantly refer to reference books, can't remember every function in every library!!


Absolutely not -- don't worry, everyone uses references to varying extents. After a while (simply through experience), you become familiar with the tools you are given. You memorise, through repeated use, the function prototypes of the most commonly used routines in the library; you learn a few common patterns; and you also get a general idea of what's in the libraries (so whilst you might not know exactly what to do, you get to know what you're looking for -- so you can bring up the documentation for the appropriate function/class/whatever when you need it).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this