PDA

View Full Version : Unwanted Deconstructors



Sadrok
12-05-01, 12:33 PM
I've got the whole story down at this link: http://sadrok.freehomepage.com/prob1.html Sorry for any popups and banners

Basically, my own CString object deconstructs after assigning a char* to it. Please look at the link and help me out. It contains my problem, source code and output.

Stu
12-05-01, 06:59 PM
Okay, here's why that deconstructor is being called. You are assigning a new value to your CString str2, which wasn't initialized--and since you didn't overload the operator=() for this type of thing, the default behavior is to call the deconstructor followed by the appropriate constructor. So, that's fine how it is, no real problem at all.

Also, on a side note, you seem to be using a lot of C in this C++ program (free, malloc, etc.). All of which is really more work than necessary. In addition, there is no such operator as 'operator char*' (your compiler might be fine with it, but it's not the ANSI/ISO standard) and you are casting to long in a depreciated manner ( (long) should be static_cast<long>(value_here) ). Finally, long isn't really a good type to return the size of a string, because a string's length can only be whole numbers greater than or equal to zero--so, the space for whole numbers less than zero will never be used. So, 'unsigned long' might be a little better, however, there is a type that is just for sizes--size_t--which is the best fit for what you want.

Most of the functionality that you are looking for is built right into the C++ STL string class, which would make your program a whole lot easier to write. Re-write example (using the string class):

string.hpp



#ifndef _STRING_HPP
#define _STRING_HPP

#include <string>

class CString
{
// Constructors
public:
CString(); // Default constructor
CString(const char * str); // Constructor taking a char* as parameter
CString(const string & str); // Constructor for a string
CString(const CString & str); // Constructor taking a reference to another CString object (not implemented)
~CString(); // Deconstructor

// Instance methods...
size_t GetLength() const; // Runs size() method
char* c_str() const; // When a char* is requested from the CString object

private:
string _itsString; // The string
};

#endif



string.cpp



#include "string.hpp"
#include <stdio.h>


/* Default constructor: NULLs _itsString */
CString::CString()
{
// Do nothing...
puts("CString::CString()");
}


/* Default deconstructor */
CString::~CString()
{
// No pointers, nothing to delete...
puts("CString::~CString()");

}

CString::CString(const char *str)
{

// Assign value...
_itsString = str;


puts("CString::CString(const char *str)");
printf(" str=%s\n", _itsString.c_str());

}

CString::CString(const string & str){

// Assign value...
_itsString = str;

}


/* Constructor taking a CString & (fully implemented) */
CString::CString(const CString & str)
{

// We use the this pointer to be sure
// it is assigned correctly; most compilers
// will not need this, but some older ones do.
this->_itsString = str.c_str();

puts("CString::CString(const CString *str)");
}

/* Returns the length of itsString with size() method */
size_t CString::GetLength() const
{

puts("CString::GetLength()");
// Return size using the class string's size() method...
return _itsString.size();

}

// Return a C style character string...
char* CString::c_str() const {

// const_cast throws away the const-ness;
// because you return a 'char *' and _itsString.c_str()
// returns a 'const char *' you need to get rid of the
// const-ness.

// c_str() is a method in class string that returns a C style
// string; a variable length array terminated by a nul character
// '\0'.
return const_cast<char *>(_itsString.c_str());

}



main.cpp



#include "string.hpp"
#include <stdio.h>

void main()
{
puts("* CString str1 = CString(\"Hello World\");");
CString str1 = CString("Hello World");
puts("* CString str2;");
CString str2;
puts("* CString str3 = \"this works\"");
CString str3 = "blah";


puts("* str2 = \"blah blah\"");
str2 = "This is the beginning of a beautiful CString object :)";

puts("* printf(str1.GetLength();");
printf("str1.GetLength() returns %d\n", str1.GetLength());
puts("* printf(str2.GetLength();");
printf("str2.GetLength() returns %d\n", str2.GetLength());
puts("* printf(str3.GetLength();");
printf("str3.GetLength() returns %d\n", str3.GetLength());

puts("* puts(str1.c_str());");
puts(str1.c_str());
puts("* puts(str2.c_str());");
puts(str2.c_str());
puts("* puts(str3.c_str());");
puts(str3.c_str());
}

Sadrok
12-06-01, 02:52 PM
Stu, thanks, but I'm not sure if it will work no my current compiler. Probably should have mentioned this: I'm programming on a 486 with a GNU compiler DJGPP, I don't think it has the type string as defined in my VC++ XSTRING file.
The basic reason for trying to do this is because I can't find any descent string class online and I want to learn more about C++ as I only have C++ in 21days at the moment, and is going to start my degree next year (although I don't think I will learn much of C++ in the first year, but I'll see)

Stu, what education do you have, I want to know in which direction I must go and every little piece of input will help me :)

Stu
12-06-01, 06:18 PM
Well, the example I put in my reply compiled fine with gcc-2.95 on a linux box (I tested it before I posted it). DJGPP (the delorie compiler) should support the STL string class--it's a slight re-write of the GNU Compiler Collection (gcc) for Windows. There are others very similar to this, like Mingw32 and Cygwin. All of which should contain the all the libraries including STLs. I know for a fact that the free Borland C++ compiler has it (http://www.borland.com/bcppbuilder/freecompiler/ ), although you have to use 'using std::string;' after the headers.

If you are happy, or rather use to, the compiler you are using--you can always just download the STL and link it in throught the command line. There are several places to get it. Here's one:

http://www.stlport.org/download.html

I haven't read "C++ in 21 Days". So, I can't really comment on it. But, if you really want to learn C++ pretty well, pick up a copy of "C++ Primer" (Third Edition or better). It's a really good book, and covers a good size chunk of the STL. If you really get into using the STL, you might want to pick up a copy of "The C++ Standard Library", which is a great reference that covers it all (but, it's a horrible read!).

As for my education, I have a Bachelor of Science in Computer Sciences and Information Systems. I have attended a ton of professional training courses in programming, database management, and replication ( all of which my previous employers paid for ;) ). But, the majority of the programming stuff I learned was through self-study (I have about 4 bookcases full of programming and database related books--all of which I have read) and "tinkering".

Finally, about the 'operator char*' thing. I didn't think that through (it was late, what can I say--I blundered). I was thinking that you were trying to overload an operator, and totally forgot about user-defined conversions (which is what 'operator char*' is). Whoops! So, that is a completely ANSI/ISO standard way to do things--contrary to what I said in the previous post. I would, however, add the c_str() method as well--since it's a fairly common method in several classes that convert to a C-style string.

Sadrok
12-07-01, 12:17 PM
Stu, thanks, I was starting wonder about operator char*...I learned that in C++ in 21days, but that's no problem.
I actually like DJGPP alot for the DOS environment, and I'm downloading STL right now. I'm also looking for a latest version of DJGPP if there is one.

One thing though, when I type info --file libgpp.info and go to the string node, it says everything about the String class but I cannot access it (include files?) since nothing of that kind is mentioned there, only how to use it inside the program block.

PS: I think of doing the BSc Computer Science and Information Technology myself nextyear. Plus some extra courses

Stu
12-07-01, 04:41 PM
Try searching for it on your hard drive. It might already be there, but it's not being linked in properly. Here's how I would do it using gcc (assuming my C++ include headers are in /usr/include/g++-v3):

g++ -fhonor-std -I/usr/include/g++-v3 -o myprogram myprogram.cpp

Sadrok
12-08-01, 12:45 PM
Oh yeah! I've downloaded the latest version of DJGPP and includes STL library and GXX-V3!!