Thread: weird code output

  1. #1
    Registered User
    Join Date
    Mar 2003
    Posts
    134

    weird code output

    Hi

    Why is the output so weird.

    at first it gives error(because of the exception), and then it says 1??? shouldnt it be the same??

    here is the code

    main.cpp
    Code:
    #include "Counter.h"
    #include "ModCounter.h"
    #include<iostream>
    using namespace std;
    
    
    void main()
    {
    	ModCounter mc1(2);
    	ModCounter mc2(4);
    
    	try
    	{
    		 cout << "mc1 == mc2: ";
    		 cout << (mc1 == mc2) << endl;
    	}
    	catch(...)
    	{
    		 cout << "Error" << endl;
    	}
    
    	Counter& c1 = mc1;
    	Counter& c2 = mc2;
    	// c1 and c2 are references of type Counter, but refer to ModCounters though.
    
    	try
    	{
    		 cout << "Again mc1 == mc2: ";
    		 cout << (c1 == c2) << endl;
    	}
    	catch(...)
    	{
    		 cout << "Error" << endl;
    	}
    }
    ModCounter.h
    Code:
    #include "Counter.h"
    
    
    #ifndef MODCOUNTER_H
    #define MODCOUNTER_H
    
    
    class ModCounter:public Counter
    {
    public:
    	ModCounter();//done
    	ModCounter(const int);//done
    	ModCounter(const ModCounter& other);//done
    	virtual const Counter& operator=(const ModCounter& other);
    	virtual bool operator==( const ModCounter& other) const;//done
    	virtual Counter operator++();//done
    	virtual Counter operator++(int);//done
    	virtual Counter operator--();//done
    	virtual Counter operator--(int);//done
    	virtual ~ModCounter();//done
    
    private:
    	
    	int limit;
    };
    
    #endif MODCOUNTER_H
    ModCounter.cpp
    Code:
    #include "ModCounter.h"
    #include "Counter.h"
    
    
    
    ModCounter::ModCounter()
    :limit(1)
    {
    }
    
    ModCounter::ModCounter(const int newLimit)
    :limit(newLimit)
    {
    }
    
    ModCounter::~ModCounter()
    {
    }
    
    ModCounter::ModCounter(const ModCounter& other)
    {
    	int i=0;
    
    	
    	
    
    	
    		for(i=0;i<other.getCounterValue()-1;i++)Counter::operator ++();
    
    		limit=other.limit;
    	
    
    	
    }
    
    Counter ModCounter::operator ++()
    {
    	if(getCounterValue()<limit-1)Counter::operator ++();
    
    	else reset();
    
    	return *this;
    
    }
    
    Counter ModCounter::operator --()
    {
    	int i=0;
    
    	if(getCounterValue()==0)
    	{
    		for(i=0;i<limit-1;i++)Counter::operator ++();
    	}
    
    	else Counter::operator --();
    	return *this;
    }
    
    Counter ModCounter::operator ++(int)
    {
    	if(getCounterValue() < limit - 1)Counter::operator++();
    	
    	else reset();
    
    	return *this;
    	
    }
    
    Counter ModCounter::operator --(int)
    {
    	int i=0;
    	if(getCounterValue() == 0 ) 
    	{
    		for (i = 0; i < limit - 1; i++)Counter::operator++();
    	}
    	else Counter::operator--();
    	return *this;
    
    }
    
    bool ModCounter::operator ==(const ModCounter& other) const
    {
    	const ModCounter *ptrMod= dynamic_cast<const ModCounter*>(&other);
    
    	if(ptrMod!=0)
    	{
    	
    	if(limit!=ptrMod->limit)throw Invalid();
    	
    	
    	}
    
    	 return (limit==ptrMod->limit && getCounterValue()==ptrMod->getCounterValue());
    }
    
    const Counter& ModCounter::operator =(const ModCounter& other)
    {
    	const ModCounter *ptrMod1= dynamic_cast<const ModCounter*>(&other);
    
    	if(ptrMod1!=0)
    	{
    	Counter::operator=(other);
    	limit = ptrMod1->limit;
    	}
    	return *ptrMod1;
    }
    Counter.h
    Code:
    #ifndef COUNTER_H
    #define COUNTER_H
    
    // DO NOT MODIFY THIS FILE
    // DO NOT MODIFY THIS FILE
    // DO NOT MODIFY THIS FILE
    
    // This class models a Counter that holds a value and allows you
    // to increment, decrement and reset.
    
    // An exception class
    class Invalid
    {
    };
    
    class Counter
    {
    public:
    	Counter();
    	// Purpose: To initialize the Counter object
    	// Requirements: -
    	// Promises: Couter's value is 0.
    	// Exception: -
    
    	virtual ~Counter();
    	// Purpose: To properly cleanup the object
    	// Requirements: -
    	// Promises: -
    	// Exception: -
    
    	Counter(const Counter& other);
    	// Purpose: To initialize the Counter object
    	// Requirements: - 
    	// Promises: Counter's value == other's value
    	// Exception: -
    
    	virtual const Counter& operator=(const Counter& other);
    	// Purpose: To copy the value from one counter to another.
    	// Requirements: -
    	// Promises: this object's value == other's value
    	// Exception: May throw an Invalid exception (for future use).
    
    	virtual bool operator==(const Counter& other) const;
    	// Purpose: Checks if two counter objects are equal (by value).
    	// Requirements: -
    	// Promises: Returns a true if value of this object == other's value.
    	// Exception: May throw an Invalid exception (for future use).
    
    	int getCounterValue() const;
    	// Purpose: To query the value of the counter object.
    	// Requirements: - 
    	// Promises: Returns the current value of the counter.
    	// Exception: - 
    
    	virtual Counter operator++();
    	// Purpose: To increment the value of the counter.
    	// Requirements: -
    	// Promises: Note the value may actually be more or less depending on implementation.
    	// Exception: -
    
    	virtual Counter operator++(int);
    	// Purpose: To increment the value of the counter.
    	// Requirements: -
    	// Promises: Note the value may actually be more or less depending on implementation.
    	// Exception: -
    
    	virtual Counter operator--();
    	// Purpose: To decrement the value of the counter.
    	// Requirements: -
    	// Promises: Note the value may actually be more or less depending on implementation.
    	// Exception: -
    
    	virtual Counter operator--(int);
    	// Purpose: To increment the value of the counter.
    	// Requirements: -
    	// Promises: Note the value may actually be more or less depending on implementation.
    	// Exception: -
    
    	virtual void reset(); 
    	// Purpose: To set the value of the counter to 0.
    	// Requirements: - 
    	// Promises: Counter's value is 0.
    	// Exception: -
    private:
    	int value;
    };
    #endif COUNTER_H
    Counter.cpp
    Code:
    // DO NOT MODIFY THIS FILE
    // DO NOT MODIFY THIS FILE
    // DO NOT MODIFY THIS FILE
    
    #include "Counter.h"
    
    Counter::Counter()
    {
    	value = 0;
    }
    
    Counter::~Counter()
    {
    }
    
    Counter::Counter(const Counter& other)
    {
    	value = other.value;
    }
    
    const Counter& Counter::operator=(const Counter& other)
    {
    	if (this != &other)
    	{
    		value = other.value;
    	}
    
    	return *this;
    }
    
    bool Counter::operator==(const Counter& other) const
    {
    	return value == other.value;
    }
    
    int Counter::getCounterValue() const
    {
    	return value;
    }
    
    Counter Counter::operator++()
    {
    	value++;
    	return *this;
    }
    
    Counter Counter::operator++(int)
    {
    	Counter temp = *this;
    	value++;
    	return temp;
    }
    
    Counter Counter::operator--()
    {
    	value--;
    	return *this;
    }
    
    Counter Counter::operator--(int)
    {
    	Counter temp = *this;
    	value--;
    	return temp;
    }
    
    void Counter::reset()
    {
    	value = 0;
    }
    Last edited by noob2c; 08-02-2003 at 05:21 PM.

  2. #2
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Well because in your first case you call ModCounter's comparison operator and the values are different so you throw an exception. Everything works as expected. However when you make them Counter's and call Counter's comparison it compares the member 'value' which gets set to 0 in the counter constructor and never changed. Therefore they are both zero and equal.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  3. #3
    Registered User
    Join Date
    Mar 2003
    Posts
    134
    but arent the references of Counter pointing to ModCounter??? shoudlnt the values be the same as the ones for ModCounter and return error?

  4. #4
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Well when you up-cast to the base class you don't have all of the derived class's members at your disposal. Like if you had a base class "Object" and a derived class "Circle" and you did

    Code:
    Object *pObj = new Circle( 0.5f, 50, 50 ); // radius, x, y
    You couldn't use pObj to access the circle's members obviously. It still has the information stored but you need to dynamic_cast to get it back to a circle. That probably doesn't answer your question.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  5. #5
    Registered User
    Join Date
    Mar 2003
    Posts
    134
    i did use dynamic cast though

  6. #6
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Originally posted by noob2c
    i did use dynamic cast though
    You use dynamic cast on ModCounter's comparison operator. You don't use it on the base class comparison operator method. I suggest debugging your code and stepping into the functions that are called. You will see that in the first case the ModCounter == is called and in the second the Counter == is called because you assigned your modcounter's to counter &'s
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  7. #7
    Registered User
    Join Date
    Mar 2003
    Posts
    134
    aaah I get it, I cant modify the base class that is Counter.h and counter.cpp they have to remain the way they are.

  8. #8
    Registered User
    Join Date
    Mar 2003
    Posts
    134
    what modification do i have to make to this code, if I want both the times an error to be thrown???

    I mean make the output like this??
    mc1 == mc2: Error
    Again mc1 == mc2:Error

  9. #9
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Originally posted by noob2c
    what modification do i have to make to this code, if I want both the times an error to be thrown???

    I mean make the output like this??
    mc1 == mc2: Error
    Again mc1 == mc2:Error
    Well for it to work like you think it should needs, it needs a small modification. You have

    Code:
    virtual bool operator==(const Counter& other) const;
    Well you need the same declaration in the derived class. Instead of that, you have

    Code:
    virtual bool operator==(const ModCounter& other) const;
    Change your comparison operator in ModCounter to exactly the same as the one in Counter and you will be set.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  10. #10
    Registered User
    Join Date
    Mar 2003
    Posts
    134
    thanks a lot dude

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Weird output of scanf and printf.
    By omnificient in forum C Programming
    Replies: 2
    Last Post: 12-05-2007, 01:28 PM
  2. << !! Posting Code? Read this First !! >>
    By kermi3 in forum Linux Programming
    Replies: 0
    Last Post: 10-14-2002, 01:30 PM
  3. << !! Posting Code? Read this First !! >>
    By kermi3 in forum Windows Programming
    Replies: 0
    Last Post: 10-14-2002, 01:29 PM
  4. << !! Posting Code? Read this First !! >>
    By kermi3 in forum Game Programming
    Replies: 0
    Last Post: 10-14-2002, 01:27 PM