|
-
May 5th, 2003, 02:32 PM
#1
Getting confused by a simple program
Ok so I think I'm having trouble with a class in my program so I created a small program to try to see what is going on. I am confused by the results. It seems that just when I think I understand C++ and OOP I find out I have been doing something wrong.
This is my BaseData class( in base.h):
Code:
class BaseData
{
public:
BaseData(){
static int ctor=0;
printf("ctor %d\n",ctor);
ctor++;
name = new char[30];
strcpy(name,"");
}
~BaseData(){
static int dtor=0;
printf("dtor %d\n",dtor);
dtor++;
delete[] name;
}
BaseData(const BaseData& p){
static int cctor=0;
printf("copy ctor %d\n",cctor);
cctor++;
name = new char[30];
*this = p;
}
BaseData& operator=(const BaseData& p){
static int assign=0;
printf("assign %d\n",assign);
assign++;
if(this != &p)
{
strcpy(name,p.name);
sensNum = p.sensNum;
}
return *this;
}
LPTSTR name;
BYTE sensNum;
};
This is my main:
Code:
#include <windows.h>
#include <stdio.h>
#include "base.h"
int main()
{
BaseData b, t1;
BaseData* t2, t3;
strcpy(b.name,"Name");
b.sensNum = 42;
printf("b: %s %d\n",b.name,b.sensNum);
t1 = b;
printf("t1: %s %d\n",t1.name,t1.sensNum);
t2 = new BaseData(b);
printf("t2: %s %d\n",t2->name,t2->sensNum);
delete t2;
/*
t3 = new BaseData; //this statement won't compile
t3 = b;
printf("t3: %s %d\n",t3->name,t3->sensNum);
delete t3;
*/
return 0;
}
The output is:
ctor 0
ctor 1
ctor 2
b: Name 42
assign 0
t1: Name 42
copy ctor 0
assign 1
t2: Name 42
dtor 0
dtor 1
dtor 2
dtor 3
First off why is the dtor called 4 times? t3 is never created so why is it begin destroyed? Second, though I think this is a result of using printfs, why is ctor 2 printed before b: Name 42? Third and most important, the commented out portion doesn't work and I do not understand why. Can someone explain? Finally does this class leak memory and/or what is wrong with it if anything? (I just started having problems in my larger program and I think it has something to do with this class).
-
May 5th, 2003, 03:15 PM
#2
The line in your code :
is the same as :
Code:
BaseData* t2;
BaseData t3; // not BaseData* t3;
-
May 5th, 2003, 03:22 PM
#3
Oh ok... now that you say that I remember. I used to put the * on the variables and not the type and recently changed.
It is amazing how much you can forget when you don't use it for awhile. I now have:
BaseData b, t1, *t2, *t3;
Well that answers my first and second questions, still have the third.
Last edited by pim42; May 5th, 2003 at 03:27 PM.
-
May 5th, 2003, 03:32 PM
#4
NEVERMIND, all I had to do now is change t3 =b to *t3=b.
you fixed all my problems and I feel stupid for having them. thanks for the help.
-
May 5th, 2003, 03:53 PM
#5
Re: Getting confused by a simple program
Originally posted by pim42
Finally does this class leak memory
Are you trying to wrap handling of char data in a class? If so, why not just use std::string?
Code:
#include <string>
class BaseData
{
private:
std::string name;
public:
BaseData(){
static int ctor=0;
printf("ctor %d\n",ctor);
ctor++;
}
};
Note that you really do not need a copy ctor, assignment operator, or destructor if you use std::string. I've cut the size of your class down to a fraction of what it was originally, does virtually the same thing as your original code does, and it is maintainable.
Regards,
Paul McKenzie
-
May 5th, 2003, 03:58 PM
#6
no this was actually a dumbed down version of a hardware sensor class. I'm interfacing a C dll so I'm using LPTSTR to match the function calls. (You might recall from pervious posts that I am required to use the same data types as the dll interface, thus no std::string).
-
May 5th, 2003, 04:42 PM
#7
Originally posted by pim42
no this was actually a dumbed down version of a hardware sensor class. I'm interfacing a C dll so I'm using LPTSTR to match the function calls. (You might recall from pervious posts that I am required to use the same data types as the dll interface, thus no std::string).
Use vector<TCHAR>, or if the DLL doesn't modify your buffer, std::string::c_str(). Same thing, less headaches.
For example, if your DLL function is prototyped like this:
Code:
void func(LPTSTR s);
The way you would call it using a vector is as follows:
Code:
vector<TCHAR> vt( 20 ); // or whatever the number of characters
//...
func(&vt[0]);
The std::vector is the gateway to interfacing to 'C' functions. The vector stores its data in contiguous memory.
To specify a char *, int *, long*, whatever *, the way to do it is to create a vector of the type desired, and just specify the address of the first element when calling the function. Therefore, your entire class interface can be simplified to this:
Code:
#include <string>
class BaseData
{
private:
std::vector<TCHAR> name;
public:
BaseData() : name(31, 0) {
static int ctor=0;
printf("ctor %d\n",ctor);
ctor++;
}
};
Again, no new, delete, copy constructor, op=, or destructor is necessary. This trick of using the std::vector instead of the "new[] / delete[]" stuff that a lot of code is littered with makes the program less problematic and easier to maintain. Also, if I want to resize the name field, all I have to do is call name.resize(). I don't have to do the "new / copy / delete " coding.
Scott Meyer's book, "Effective STL", has an entire chapter dedicated to interfacing to 'C' functions using the standard containers.
Regards,
Paul McKenzie
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|