Thread: constructor problems

  1. #1
    Registered User
    Join Date
    Nov 2006
    Posts
    34

    Cool constructor problems

    I'm writing a program that is supposed to simulate a JK flip flop. Thing is it's been a while since I've written in C+ and I can't figure out how to initialize my variables (*embarrassed*).

    Here is my files:

    Code:
    #ifndef JKflipFlop_h
    #define JKflipFlop_h
    
    #include <iostream>
    
    class JKFlipFlop
    {
    public:
    	JKFlipFlop();
    	JKFlipFlop(int, int, int, int, int);
    	void setJandK(int, int, int, int, int);
    	int JKFlip(int ipJ, int ipK, int ipQ);
    	int enableJK(int inputWire, int ipJ, int ipK, int ipQ);
    	~JKFlipFlop();
    
    private:
    
    	int ipJ; 
    	int ipK;
    	int ipQ;
    	int ipWireJ;
    	int ipWireK;
    
    };
    #endif
    
    #include "JKflipFlop.h"
    #include <iostream>
    
    using namespace std;
    
    
    JKFlipFlop::JKFlipFlop()
    {
    			
    }
    
    /*
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         constructor for JKfipFlop()
    	 make a copy of J, K and Q for manipulation.
    	 ipJ = J, ipK = K, ipQ= Q, ipWire = inputWire
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    */ 
    
    JKFlipFlop::JKFlipFlop(int J , int K , int Q , int inputWireA , int inputWireB )
    {
    	setJandK(J, K, Q, inputWireA, inputWireB);
    }
    
    
    /*
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         function to set ipK, ipK and ipQ
    	 make a copy of J,K and Q for manipulation.
    	 ipJ = J, ipK = K, ipQ = Q, ipWire = inputWire
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    */ 
    
    void JKFlipFlop::setJandK(int J, int K, int Q, int inputWireA, int inputWireB)
    {
    	ipJ = J;
    	ipK = K;
    	ipQ = Q;
    	ipWireJ = inputWireA;
    	ipWireK = inputWireB;
    }
    
    /*
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         Enable JK is called to start the flipFlop function.
    	 If the inputWire is low, JKFlipFlop is not called and Q retains the ame state.
    	 If the inputWire is High, JKFlipFlop is called and the wires will be processed.
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    */
    int JKFlipFlop::enableJK(int ipWireA, int ipJ, int ipK, int ipQ)
    {
    
    	if(ipWireA == 0)
    	{
    		
    		return ipQ;
    	}
    	else
    	{
    		
    		return JKFlip(ipWireJ, ipWireK, ipQ);
    	}
    	
    }
    
    /*
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         JK flip:
    	 -if enable is low, Q or Q' will not be changed, and therefore
    	  the JKFlipFlop function will not be called.
    	 -if enable is high && J and K are low Q and Q' will not be changed.
    	 -                     J is low, K is high Q is set low and Q' is high
    	 -					   J is high and K is low, Q is set to high, Q' is low
    	 -                     J is high and K is high, determine the value of Q and 
    	                           make it opposite.
    
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    */
    int JKFlipFlop::JKFlip(int ipJ, int ipK, int ipQ)
    {
    	cout << "ipJ = " << ipJ;
    	cout << ", ipK = " << ipK ;
    	cout << ", ipQ = " << ipQ << endl;
    	cout << endl;
    	if (ipJ == 0 && ipK == 0)
    	{
    		
    		return ipQ;   //ipQ is unchanged
    	}
    	if (ipJ == 0 && ipK == 1)
    	{
    		ipQ = 0;  //ipQ is reset
    		cout << "In J low K high" << ipQ << endl;
    		
    	}
    	if (ipJ == 1 && ipK == 0)
    	{
    		
    	}
    	if (ipJ == 1 && ipK ==1)
    	{
    		if(ipQ == 0)
    		{
    			ipQ = 1;
    		}
    		else
    		{
    			ipQ = 0;
    		}
    	}
    	return ipQ;
    	
    }
    
    
    
    JKFlipFlop::~JKFlipFlop()
    {
    	
    }
    
    
    #include "flipFlop.h"
    #include "JKFlipFlop.h"
    
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
    	
    	JKFlipFlop FJK;
    
    	int ipWireA = 0;
    	int ipWireB = 0;
    	
    	int Jtest = 0;
    	int Ktest = 0;
    	int Qtest = 0;
    
    	int outputWire = 0;
    
    		
    	ipWireA = 0;
    	Jtest = 0;
    	Ktest = 0;
    	Qtest = 0;
    
    	outputWire = FJK.enableJK(ipWireA, Jtest, Ktest, Qtest);
    	cout << "Result of JK (ipWire 0, J low, K low): " << outputWire << endl;
    	
    	cout << endl;
    	ipWireA = 1;
    	Jtest = 0;
    	Ktest = 0;
    
    	outputWire = FJK.enableJK(ipWireA, Jtest, Ktest, Qtest);
    	cout << "Result of JK (ipWire 1, J low, K low): " << outputWire << endl;
    	
    	cout << endl;
    	ipWireA = 1;
    	Jtest = 0;
    	Ktest = 1;
    
    	outputWire = FJK.enableJK(ipWireA, Jtest, Ktest, Qtest);
    	cout << "Result of JK (ipWire 1, J low, K high): " << outputWire << endl;
    	
    	cout << endl;
    	ipWireA = 1;
    	Jtest = 1;
    	Ktest = 0;
    
    	outputWire = FJK.enableJK(ipWireA, Jtest, Ktest, Qtest);
    	cout << "Result of JK (ipWire 1, J high, K low): " << outputWire << endl;
    	
    	cout << endl;
    	ipWireA = 1;
    	Jtest = 1;
    	Ktest = 1;
    
    	outputWire = FJK.enableJK(ipWireA, Jtest, Ktest, Qtest);
    	cout << "Result of JK (ipWire 1, J = 1, K = 1): " << outputWire << endl;
    	
    	return 0;
    }

    thank you in advance for your help

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    How does it not work?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Nov 2006
    Posts
    34
    Quote Originally Posted by laserlight View Post
    How does it not work?
    It puts out garbage. I need to initialize my variables, probably in my default constructor. But I've tried it several ways and it hasn't worked. Like for instance:

    ipJ = 0;

    does not change the output. If you run the code -87380928 comes out (or something similar). That means I'm not initializing my variables correctly with the constructor.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Like for instance:

    ipJ = 0;

    does not change the output.
    Hold on: are you referring to main()? There is no such statement in your default constructor.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Hold on: are you referring to main()? There is no such statement in your default constructor.
    I think tms43 means that adding that line to the default constructor doesn't completely solve the problem: the program still outputs garbage which is probably due to uninitialized variables.

    Did you try initializing all of the class members, not just ipJ?

    Your compiler should be able to warn you about uninitialized variables if you enable compiler warnings, but you seem to have already identified the problem as uninitialized variable(s).
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  6. #6
    Registered User
    Join Date
    Nov 2006
    Posts
    34
    yes, I tried initializing all of them using the constructor without parameters. So, I'm thinking that what I've done will never get me to what I need it to do. (*gasp*) This should be so easy. I suppose I will break out the data structures books and get back to basics. I was hoping that it was something really obvious and I wouldn't have to do that.

    Oh well ...

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I don't know exactly what you expect your code to do, but changing your constructor to do:
    Code:
    JKFlipFlop::JKFlipFlop()
    {
    	ipJ = 0;
    	ipK = 0;
    	ipWireJ = 0;
    	ipWireK = 0;
    }
    changes it from giving random large numbers into doing "nice small numbers":
    Code:
    Result of JK (ipWire 0, J low, K low): 0
    
    ipJ = 0, ipK = 0, ipQ = 0
    
    Result of JK (ipWire 1, J low, K low): 0
    
    ipJ = 0, ipK = 0, ipQ = 0
    
    Result of JK (ipWire 1, J low, K high): 0
    
    ipJ = 0, ipK = 0, ipQ = 0
    
    Result of JK (ipWire 1, J high, K low): 0
    
    ipJ = 0, ipK = 0, ipQ = 0
    
    Result of JK (ipWire 1, J = 1, K = 1): 0
    Enabling the highest level of warnings gives this:
    Code:
    jkflipflop.cpp(53): warning C4100: 'ipK' : unreferenced formal parameter
    jkflipflop.cpp(53): warning C4100: 'ipJ' : unreferenced formal parameter
    That's this code:
    int JKFlipFlop::enableJK(int ipWireA, int ipJ, int ipK, int ipQ)
    {
    
    	if(ipWireA == 0)
    	{
    		
    		return ipQ;
    	}
    	else
    	{
    		
    		return JKFlip(ipWireJ, ipWireK, ipQ);
    	}
    	
    }
    jk.cpp(18): warning C4189: 'ipWireB' : local variable is initialized but not referenced
    And that's inside main.
    I hope this helps.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    After reading this Wikipedia article, I'm guessing that you're looking for this output (debugging output stripped, comments in blue):
    Code:
    Result of JK (ipWire 0, J low, K low): 0  // query
    Result of JK (ipWire 1, J low, K low): 1  // query
    Result of JK (ipWire 1, J low, K high): 0  // clear
    Result of JK (ipWire 1, J high, K low): 1  // set
    Result of JK (ipWire 1, J = 1, K = 1): 0  // toggle
    Now I'm looking at your code . . .
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
    int JKFlipFlop::JKFlip(int ipJ, int ipK, int ipQ)
    {
    	cout << "ipJ = " << ipJ;
    	cout << ", ipK = " << ipK ;
    	cout << ", ipQ = " << ipQ << endl;
    	cout << endl;
    ...
    	if (ipJ == 1 && ipK == 0)
    	{
    		
    	}
    Whilst there is nothing wrong as such in this code, it's a bit confusing, since it uses parameters to the function with exactly the same name as the members of the class.

    Also note the empty if-statement - I don't know what it's supposed to do, but perhaps it should be doing something?

    Similar problems apply to enableJK, it also has ipJ, ipK and ipQ as inputs, which are also members of the class.

    Edit: And I can confirm that when there is a parameter and a member variable with the same name, the parameter is used.

    --
    Mats
    Last edited by matsp; 09-05-2007 at 01:48 PM.
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Okay, here's your problem. In JKFlipFlop::enableJK(), you pass JKFlip() the class's member variables, which are never set to anything, instead of the function's parameters. When you use this code (blue code added or changed):
    Code:
    JKFlipFlop::JKFlipFlop()
    {
    	ipJ = 0;
    	ipK = 0;
    	ipWireJ = 0;
    	ipWireK = 0;
    }
    
    // ...
    
    int JKFlipFlop::enableJK(int ipWireA, int ipJ, int ipK, int ipQ)
    {
    
    	if(ipWireA == 0)
    	{
    		
    		return ipQ;
    	}
    	else
    	{
    		
    		return JKFlip(ipJ, ipK, ipQ);
    	}
    	
    }
    
    // ...
    
    int JKFlipFlop::JKFlip(int ipJ, int ipK, int ipQ)
    {
    	cout << "ipJ = " << ipJ;
    	cout << ", ipK = " << ipK ;
    	cout << ", ipQ = " << ipQ << endl;
    	cout << endl;
    	if (ipJ == 0 && ipK == 0)
    	{
    		
    		return ipQ;   //ipQ is unchanged
    	}
    	if (ipJ == 0 && ipK == 1)
    	{
    		ipQ = 0;  //ipQ is reset
    		cout << "In J low K high" << ipQ << endl;
    		
    	}
    	if (ipJ == 1 && ipK == 0)
    	{
    		ipQ = 1;  //ipQ is set
    	}
    	if (ipJ == 1 && ipK ==1)
    	{
    		if(ipQ == 0)
    		{
    			ipQ = 1;
    		}
    		else
    		{
    			ipQ = 0;
    		}
    	}
    	return ipQ;
    	
    }
    you get this output:
    Code:
    Result of JK (ipWire 0, J low, K low): 0
    
    ipJ = 0, ipK = 0, ipQ = 0
    
    Result of JK (ipWire 1, J low, K low): 0
    
    ipJ = 0, ipK = 1, ipQ = 0
    
    In J low K high0
    Result of JK (ipWire 1, J low, K high): 0
    
    ipJ = 1, ipK = 0, ipQ = 0
    
    Result of JK (ipWire 1, J high, K low): 1
    
    ipJ = 1, ipK = 1, ipQ = 0
    
    Result of JK (ipWire 1, J = 1, K = 1): 1
    I'm not sure if that's what you wanted, but it's a step in the right direction.

    If you wanted to use the class's variables, assign values to them in JKFlipFlop::enableJK(), and pass those on.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Actually, I think part of the solution is to use the correct form of the constructur:
    Code:
    	JKFlipFlop FJK(0, 0, 0, 0, 0);
    You could actually use some more of C++'s features and default all the values to zero too:
    Code:
    	JKFlipFlop();  // Remove
    	JKFlipFlop(int J = 0, int K = 0 , int Q = 0 , int inputWireA = 0 , int inputWireB = 0);  // Replace the other constructor with this one.
    	JKFlipFlop FJK; // Use the default values.
    Edit with some further editing, I get what I think is the correct result:
    Code:
    Result of JK (ipWire 0, J low, K low): 0
    Result of JK (ipWire 1, J low, K low): 0
    Result of JK (ipWire 1, J low, K high): 0
    Result of JK (ipWire 1, J high, K low): 1
    Result of JK (ipWire 1, J = 1, K = 1): 0
    To get this, I removed the parameters to JKFlip all together, and I removed the Q from enableJK.
    Code:
    // in jkflipflop.h:
    	int JKFlip();
    	int enableJK(int inputWire, int ipJ, int ipK);
    ---
    // in jkflipflop.cpp:
    int JKFlipFlop::enableJK(int ipWireA, int ipJ, int ipK)
    {
    	this->ipJ = ipJ;
    	this->ipK = ipK;
    	if(ipWireA) {
    		ipQ = JKFlip();
    	}
    	return ipQ;
    	
    }
    
    // ...
    
    int JKFlipFlop::JKFlip()
    {
    	cout << "ipJ = " << ipJ;
    	cout << ", ipK = " << ipK ;
    	cout << ", ipQ = " << ipQ << endl;
    	cout << endl;
    	if (ipJ == 0 && ipK == 0)
    	{
    		return ipQ;   //ipQ is unchanged
    	}
    	if (ipJ == 0 && ipK == 1)
    	{
    		ipQ = 0;  //ipQ is reset
    		cout << "In J low K high" << ipQ << endl;
    		
    	}
    	if (ipJ == 1 && ipK == 0)
    	{
    		ipQ = 1;
    	}
    	if (ipJ == 1 && ipK ==1)
    	{
    		if(ipQ == 0)
    		{
    			ipQ = 1;
    		}
    		else
    		{
    			ipQ = 0;
    		}
    	}
    	return ipQ;
    	
    }

    --
    Mats
    Last edited by matsp; 09-05-2007 at 02:15 PM.
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    The reason JKFlip didn't work previously was that the ipQ value didn't get set permanently, so the next time around, it was still zero, so it came out as one - because it was setting the parameter into the function, not the member of the class.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    Registered User
    Join Date
    Nov 2006
    Posts
    34
    by george I think you saved the day! I was on the same track, but missed the ipWireJ... GREAT catch.

    Thank you very much

  14. #14
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    The last if-statement in jkflip can be made shorter by using the built-in "not" operator !:
    Code:
    	if (ipJ == 1 && ipK ==1)
    	{
    		ipQ = !ipQ;
    	}
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  15. #15
    Registered User
    Join Date
    Nov 2006
    Posts
    34
    nice touch! It's always good to shorten code AND make it more readible. Thanks again!

Popular pages Recent additions subscribe to a feed