CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7
  1. #1
    Join Date
    Jan 2003
    Posts
    159

    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).

  2. #2
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,725
    The line in your code :

    Code:
    BaseData* t2, t3;
    is the same as :

    Code:
    BaseData* t2;
    BaseData   t3;   // not BaseData* t3;

  3. #3
    Join Date
    Jan 2003
    Posts
    159
    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.

  4. #4
    Join Date
    Jan 2003
    Posts
    159
    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.

  5. #5
    Join Date
    Apr 1999
    Posts
    27,449

    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

  6. #6
    Join Date
    Jan 2003
    Posts
    159
    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).

  7. #7
    Join Date
    Apr 1999
    Posts
    27,449
    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
  •  





Click Here to Expand Forum to Full Width

Featured