Internal Workings Of The = Operator?

This is a discussion on Internal Workings Of The = Operator? within the C++ Programming forums, part of the General Programming Boards category; OK, I have some very complicated datatypes, that have member functions executing as THREADS constantly. There will be at any ...

  1. #1
    That Creepy Network Guy DeepBlackMagic's Avatar
    Join Date
    Feb 2003
    Posts
    265

    Internal Workings Of The = Operator?

    OK, I have some very complicated datatypes, that have member functions executing as THREADS constantly. There will be at any given time 1 to 3 member functions running constantly as a thread in the object. BTW the object is called ALARM. Lets you set an absoloute time, function * and void * and when the time is reached it will simply execute the function via pointer, passing it the void * as data. So i have alarm1 = somestuff. same with alarms 2 and 3. If i say alarm1 = alarm2, what happens? These running threads dont get stopped to my knowledge, So would what alarm1 was still be running in memory? Would the destructor be called? Is it simply freed memory?

    I have posted the as of yet UNFINISHED but WORKING code for both parts below, and i NEED input to know how i should go about protecting these threads from accidentally getting cut, or knowing what i need to do to make it work properly.

    Compiles Clean on MS VC++6.0 SP5:

    Code for main.cpp:
    Code:
    #include "alarm.h"
    #include <iostream>
    
    
    void myfunc(void * spaz)
    {
    	int * x = static_cast<int*>(spaz);
    	std::cout << "asdf: " << *x << std::endl;
    	return;
    }
    
    int main()
    {
    	int x;
    	x = 4;
    	void *bob = &x;
    
    	myfunc(bob);
    /*year, month, day, hour, minute, second, function, data to pass*/
    	Alarm thealarm = Alarm(2003,10,10,17,11,30,*myfunc,bob);
    	thealarm = Alarm(2003,10,10,17,11,20,*myfunc,bob);
    	while(1){Sleep(1000);}
    	return 0;
    }
    Code for alarm.h
    Code:
    #ifndef __ALARM_H__
    #define __ALARM_H__
    
    //DISABLE STUPID STL WARNINGS
    #pragma warning(disable:4786)
    
    #include <string>
    #include <vector>
    #include <sstream>
    #include <time.h>
    #include <windows.h>
    
    class Alarm
    {
    	public:
    		Alarm();
    		Alarm(int inYear, int inMonth, int inDay, int inHour, int inMinute, int inSecond, void (*inPtr)(void *),void * inPtrData);
    		~Alarm();
    
    	private:
    		//Called In The Constructor To Start Checking If We Should Execute
    		static void CreateAlarmCheckThread(void *param)
    		{
    			Alarm *thisAlarm = static_cast<Alarm*>(param);
    			thisAlarm->AlarmCheckThread();
    		}
    		//Loop forever to see if we should alarm.
    		void AlarmCheckThread();
    		//Update the nowTime variables with the current time
    		void UpdateTime();
    		//Do we want to terminate the thread?
    		bool die;
    		//Time to execute
    		int exeYear;
    		int exeMonth;
    		int exeDay;
    		int exeHour;
    		int exeMinute;
    		int exeSecond;
    		void (*exePtr)(void *);
    		void * exePtrData;
    		//Time now
    		int nowYear;
    		int nowMonth;
    		int nowDay;
    		int nowHour;
    		int nowMinute;
    		int nowSecond;
    		//variables
    };
    
    Alarm::Alarm()
    {
    	//We are ready to terminate because we have no vars yet.
    	die = true;
    	//No variables to initiate yet.
    	return;
    }
    
    Alarm::Alarm(int inYear, int inMonth, int inDay, int inHour, int inMinute, int inSecond, void (* inPtr)(void *), void * inPtrData)
    {
    	//We are not ready to terminate
    	die = false;
    	//Set Other Variables
    	exeYear = inYear;
    	exeMonth = inMonth;
    	exeDay = inDay;
    	exeHour = inHour;
    	exeMinute = inMinute;
    	exeSecond = inSecond;
    	exePtr = inPtr;
    	exePtrData = inPtrData;
    	//Create The AlarmCheckThread To See If We Should Alarm
    	CreateThread(0,0,(LPTHREAD_START_ROUTINE)CreateAlarmCheckThread,this,0,0);
    	//Done
    	return;
    }
    
    Alarm::~Alarm()
    {
    	//Tell the AlarmCheckThread to terminate.
    	die = true;
    	//Wait for the AlarmCheckThread to terminate.
    	Sleep(1500);
    }
    
    void Alarm::AlarmCheckThread()
    {
    	//Do until the destructor is called
    	while(!die)
    	{
    		UpdateTime();
    		if(exeYear==nowYear&&exeMonth==nowMonth&&exeDay==nowDay&&exeHour==nowHour&&exeMinute==nowMinute&&exeSecond==nowSecond)
    		{ exePtr(exePtrData); Sleep(1000); }
    		//Check to see if i should Alarm
    		Sleep(500);
    	}
    }
    
    void Alarm::UpdateTime()
    {
    		time_t rawtime;
    		struct tm * timeinfo;
    
    		time ( &rawtime );
    		timeinfo = localtime ( &rawtime );
    
    		std::string timestring = asctime(timeinfo);
    		//Contains: Thu Oct 09 20:38:45 2003
    		//5 [0-4] strings, day. month, ##date ##hour:##minutes:##seconds ####year
    		for(int i=0;i<timestring.size();i++)
    		{
    			if (timestring[i]==':') { timestring[i] = ' '; }
    		}
    		//Contains: Thu Oct 09 20 38 45 2003
    		//7 [0-6] strings, day. month, ##date ##hour ##minutes ##seconds ####year
    	
    		std::vector<std::string> words;
    
    		std::istringstream is(timestring);
    		std::string word;
    		while(is>>word)
    		{ words.push_back(word); }
    
    		nowYear = atoi(words[6].c_str());
    		//Thx Local$$$$$.
    		nowMonth = ( strstr( "Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec", words[1].c_str() ) - "Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec" ) / 4 + 1;
    		nowDay = atoi(words[2].c_str());
    		nowHour = atoi(words[3].c_str());
    		nowMinute = atoi(words[4].c_str());
    		nowSecond = atoi(words[5].c_str());
    
    		return;
    }
    
    
    /*LOTS AND LOTS OF UNFINISHED CODE*/
    
    class AlarmSystem
    {
    	public:
    		AlarmSystem();
    		~AlarmSystem();
    		AddAlarm();
    		DelAlarm();
    
    	private:
    		std::vector<Alarm> alarms;
    };
    
    
    #endif

  2. #2
    Cat
    Cat is offline
    Registered User
    Join Date
    May 2003
    Posts
    1,571
    If you don't overload operator=, then the default is to shallow copy every data member -- so anything that you need to stop, or free, etc. about the first data member is lost.

    Most importantly, I think, is that your alarm check thread continues. Your destructor is never called.

    In general, you need the big 3 -- because you need a custom destructor, you need a custom assignment operator and copy constructor, because the auto-generated ones won't work properly.
    You ever try a pink golf ball, Wally? Why, the wind shear on a pink ball alone can take the head clean off a 90 pound midget at 300 yards.

  3. #3
    That Creepy Network Guy DeepBlackMagic's Avatar
    Join Date
    Feb 2003
    Posts
    265
    Thank you for your input cat, I respect your opinion alot.

    Are you saying that when it copys the object, the destructor of the old object that is no longer owned by a variable name isnt called? Is the old thread processing the new data? Are there 2 threads running at once? If i kill the thread in the copy, is it really killing the origonal one?

    I guess what i dont understand is what happens when i allow the compiler to define how it is copied. When i copy what exactly is copied, just the data members and not the instructions being executed by another thread? At what point if any are constructors and destructors called?

    I dont suppose there is a prety diagram or flow chart somebody could provide so i can know whats going to happen to my poor defenceless objects. I have other objects that behave similarly and have never really thought about what happens if somebody were to assign them with just an = operator, as i never intended it to happen like that until now.

    If i executed the STD::Copy function would it have the same effect as the = operator? Are there other things that copy or assign that i should be aware of?

    Thanks for all the help guys.

  4. #4
    Cat
    Cat is offline
    Registered User
    Join Date
    May 2003
    Posts
    1,571
    Originally posted by DeepBlackMagic
    Thank you for your input cat, I respect your opinion alot.

    Are you saying that when it copys the object, the destructor of the old object that is no longer owned by a variable name isnt called?
    The "old object" (the lefthand side) gets the data of the "new object" (right hand side); afterward, they are still 2 separate objects which contain the same data. The "old object" is not destroyed, the destructor is never called. The thread continues to execute, but next time it does, it will see the new data in place of the old.

    Essentially, all the copy does is the following:

    lhs.exeYear = rhs.exeYear;
    lhs.exeMonth = rhs.exeMonth;
    // Etc. for every variable

    Is the old thread processing the new data? Are there 2 threads running at once?
    Yes to both, assuming both of the alarms were running threads to begin with. The default operators will neither create nor destroy your threads.

    If i kill the thread in the copy, is it really killing the origonal one?
    No. After the copy, you have two identical alarms (so the event would be done twice, once by each alarm). You can start or stop one copy without affecting the other.

    Now, this does get a little trickier. This:

    Alarm temp;
    temp = alarm;

    would use the operator= for Alarm. In this case, because the original thread in temp was never started, the thread still is not started when the operator= happens.

    This:

    Alarm temp = alarm;

    does *not* use operator=. It uses the copy constructor, and is exactly the same as:

    Alarm temp(alarm);

    This uses the default generated copy constructor, which has the same effect as the default assignment operator. In both cases, temp does not have an executing thread, because it was never started for either.
    Last edited by Cat; 10-11-2003 at 12:09 AM.
    You ever try a pink golf ball, Wally? Why, the wind shear on a pink ball alone can take the head clean off a 90 pound midget at 300 yards.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Assignment Operator, Memory and Scope
    By SevenThunders in forum C++ Programming
    Replies: 47
    Last Post: 03-31-2008, 07:22 AM
  2. Smart pointer class
    By Elysia in forum C++ Programming
    Replies: 63
    Last Post: 11-03-2007, 08:05 AM
  3. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 03:39 PM
  4. Operator Overloading (Bug, or error in code?)
    By QuietWhistler in forum C++ Programming
    Replies: 2
    Last Post: 01-25-2006, 08:38 AM
  5. operator overloading and dynamic memory program
    By jlmac2001 in forum C++ Programming
    Replies: 3
    Last Post: 04-07-2003, 12:51 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21