Monday, March 2, 2015

Common operators to overload


Assignment Operator

X& X::operator=(X rhs) { swap(rhs); return *this; }



Bitshift Operators (used for Stream I/O)

The bitshift operators << and >>, although still used in hardware interfacing for the bit-manipulation functions they inherit from C, have become more prevalent as overloaded stream input and output operators in most applications. For guidance overloading as bit-manipulation operators, see the section below on Binary Arithmetic Operators. For implementing your own custom format and parsing logic when your object is used with iostreams, continue.

The stream operators, among the most commonly overloaded operators, are binary infix operators for which the syntax specifies no restriction on whether they should be members or non-members. Since they change their left argument (they alter the stream’s state), they should, according to the rules of thumb, be implemented as members of their left operand’s type. However, their left operands are streams from the standard library, and while most of the stream output and input operators defined by the standard library are indeed defined as members of the stream classes, when you implement output and input operations for your own types, you cannot change the standard library’s stream types. That’s why you need to implement these operators for your own types as non-member functions. The canonical forms of the two are these:

std::ostream& operator<<(std::ostream& os, const T& obj) { // write obj to stream return os; } std::istream& operator>>(std::istream& is, T& obj) { // read obj from stream if( /* no valid object of T found in stream */ ) is.setstate(std::ios::failbit); return is; }

When implementing operator>>, manually setting the stream’s state is only necessary when the reading itself succeeded, but the result is not what would be expected.
Function call operator
The function call operator, used to create function objects, also known as functors, must be defined as a member function, so it always has the implicit this argument of member functions. Other than this it can be overloaded to take any number of additional arguments, including zero.
Throughout the C++ standard library, function objects are always copied. Your own function objects should therefore be cheap to copy. If a function object absolutely needs to use data which is expensive to copy, it is better to store that data elsewhere and have the function object refer to it.

Comparison operators

The binary infix comparison operators should, according to the rules of thumb, be implemented as non-member functions1. The unary prefix negation ! should (according to the same rules) be implemented as a member function. (but it is usually not a good idea to overload it.)

The standard library’s algorithms (e.g. std::sort()) and types (e.g. std::map) will always only expect operator< to be present. However, the users of your type will expect all the other operators to be present, too, so if you define operator<, be sure to follow the third fundamental rule of operator overloading and also define all the other boolean comparison operators. The canonical way to implement them is this:

inline bool operator==(const X& lhs, const X& rhs){ /* do actual comparison */ }

inline bool operator!=(const X& lhs, const X& rhs){return !operator==(lhs,rhs);}


inline bool operator< (const X& lhs, const X& rhs){ /* do actual comparison */ }


inline bool operator> (const X& lhs, const X& rhs){return operator< (rhs,lhs);}


inline bool operator<=(const X& lhs, const X& rhs){return !operator> (lhs,rhs);}


inline bool operator>=(const X& lhs, const X& rhs){return !operator< (lhs,rhs);}


The important thing to note here is that only two of these operators actually do anything, the others are just forwarding their arguments to either of these two to do the actual work.
The syntax for overloading the remaining binary boolean operators (||, &&) follows the rules of the comparison operators. However, it is very unlikely that you would find a reasonable use case for these2.

1 As with all rules of thumb, sometimes there might be reasons to break this one, too. If so, do not forget that the left-hand operand of the binary comparison operators, which for member functions will be *this, needs to be const, too. So a comparison operator implemented as a member function would have to have this signature:
bool operator<(const X& rhs) const { /* do actual comparison with *this */ } (Note the const at the end.)

2 It should be noted that the built-in version of || and && use shortcut semantics. While the user defined ones (because they are syntactic sugar for method calls) do not use shortcut semantics. User will expect these operators to have shortcut semantics, and their code may depend on it, Therefore it is highly advised NEVER to define them.
Arithmetic Operators

Unary arithmetic operators

The unary increment and decrement operators come in both prefix and postfix flavor. To tell one from the other, the postfix variants take an additional dummy int argument. If you overload increment or decrement, be sure to always implement both prefix and postfix versions. Here is the canonical implementation of increment, decrement follows the same rules:

class X { X& operator++() { // do actual increment return *this; } X operator++(int) { X tmp(*this); operator++(); return tmp; } };

Note that the postfix variant is implemented in terms of prefix. Also note that postfix does an extra copy.2
Overloading unary minus and plus is not very common and probably best avoided. If needed, they should probably be overloaded as member functions.

2 Also note that the postfix variant does more work and is therefore less efficient to use than the prefix variant. This is a good reason to generally prefer prefix increment over postfix increment. While compilers can usually optimize away the additional work of postfix increment for built-in types, they might not be able to do the same for user-defined types (which could be something as innocently looking as a list iterator). Once you got used to do i++, it becomes very hard to remember to do ++i instead when i is not of a built-in type (plus you'd have to change code when changing a type), so it is better to make a habit of always using prefix increment, unless postfix is explicitly needed.

Binary arithmetic operators

For the binary arithmetic operators, do not forget to obey the third basic rule operator overloading: If you provide +, also provide +=, if you provide -, do not omit -=, etc. Andrew Koenig is said to have been the first to observe that the compound assignment operators can be used as a base for their non-compound counterparts. That is, operator + is implemented in terms of +=, - is implemented in terms of -= etc.
According to our rules of thumb, + and its companions should be non-members, while their compound assignment counterparts (+= etc.), changing their left argument, should be a member. Here is the exemplary code for += and +, the other binary arithmetic operators should be implemented in the same way:

class X { X& operator+=(const X& rhs) { // actual addition of rhs to *this return *this; } }; inline X operator+(X lhs, const X& rhs) { lhs += rhs; return lhs; }

operator+= returns its result per reference, while operator+ returns a copy of its result. Of course, returning a reference is usually more efficient than returning a copy, but in the case of operator+, there is no way around the copying. When you write a + b, you expect the result to be a new value, which is why operator+ has to return a new value.3 Also note that operator+ takes its left operand by copy rather than by const reference. The reason for this is the same as the reason giving for operator= taking its argument per copy.
The bit manipulation operators ~ & | ^ << >> should be implemented in the same way as the arithmetic operators. However, (except for overloading << and >> for output and input) there are very few reasonable use cases for overloading these.

3 Again, the lesson to be taken from this is that a += b is, in general, more efficient than a + b and should be preferred if possible.

Array Subscripting

The array subscript operator is a binary operator which must be implemented as a class member. It is used for container-like types that allow access to their data elements by a key. The canonical form of providing these is this:

class X { value_type& operator[](index_type idx); const value_type& operator[](index_type idx) const; // ... };

Unless you do not want users of your class to be able to change data elements returned by operator[] (in which case you can omit the non-const variant), you should always provide both variants of the operator.If value_type is known to refer to a built-in type, the const variant of the operator should return a copy instead of a const reference.

Overloading new and delete

The C++ standard library comes with a set of predefined new and delete operators. The most important ones are these:

void* operator new(std::size_t) throw(std::bad_alloc); 
void  operator delete(void*) throw(); 
void* operator new[](std::size_t) throw(std::bad_alloc); 

void  operator delete[](void*) throw(); 

When new is overloaded, delete  must be overloaded.

When to overload new and delete?

1. To Detect Usage Errors
2. To Improve Efficiency(speed & memory)
3. To Collect Memory Usage Statistics
4. To compensate for sub optimal memory alignment
5. To obtain unconventional behavior


Thursday, February 9, 2012

SCARY iterator


 Acronym SCARY “describes assignments and initializations that are Seemingly erroneous (Constrained by conflicting generic parameters), but Actually work with the Right implementation (unconstrained bY the conflict due to minimized dependencies).”  



Tuesday, November 29, 2011

31 Windows Shortcuts


  1. Component Services – comexp.msc
  2. Computer Management – compmgmt.msc
  3. Device Manager – devmgmt.msc
  4. Disk Defrag – dfrg.msc
  5. Disk Managment – diskmgmt.msc
  6. Event Viewer – eventvwr.msc
  7. Group Policies – gpedit.msc
  8. Local Security Settings – secpol.msc
  9. Local Users and Groups – lusrmgr.msc
  10. Performance Monitor – perfmon.msc
  11. Resultant Set of Policies – rsop.msc
  12. Services – services.msc
  13. Shared Folders – fsmgmt.msc
  14. access.cpl - Accessibility controls Keyboard(1), Sound(2), Display(3), Mouse(4), General(5) 
  15. appwiz.cpl - Add/Remove Programs  
  16. desk.cpl - Display properties  Themes(5), Desktop(0), Screen Saver(1), Appearance (2), Settings(3)
  17. hdwwiz.cpl - Add hardware   
  18. inetcpl.cpl - Configure Internet Explorer and Internet properties  General(0), Security(1), Privacy(2), Content(3), Connections(4), Programs(5), Advanced(6) 
  19. intl.cpl - Regional settings  Regional Options(1), Languages(2), Advanced(3) 
  20. joy.cpl - Game controllers   
  21. main.cpl - Mouse properties and settings  Buttons(0), Pointers(1), Pointer Options(2), Wheel(3), Hardware(4) 
  22. main.cpl,@1  Keyboard properties  Speed(0), Hardware (1) 
  23. mmsys.cpl Sounds and Audio  Volume(0), Sounds(1), Audio(2), Voice(3), Hardware(4) 
  24. ncpa.cpl Network properties   
  25. nusrmgr.cpl User accounts   
  26. powercfg.cpl Power configuration  Power Schemes, Advanced, Hibernate, UPS (Tabs not indexed) 
  27. sysdm.cpl System properties General(0), Computer Name(1), Hardware(2), Advanced(3), System Restore(4), Automatic Updates(5), Remote (6) 
  28. telephon.cpl Phone and modem options  Dialing Rules(0), Modems(1), Advanced(2)
  29. timedate.cpl Date and time properties  Date & Time(0), Time Zone(1), Internet Time (no index) 
  30. sc create [service name] - to add
  31. sc delete [service name] - to delete

Thursday, September 1, 2011

Catch the Bug - 1

After a long time, I am restarting this blog.

Today I am introducing a programming bug.
Look at the pseudo code below.

unsigned long uCount;
unsigned long uMaxVal;

....
....

//uMaxVal assigned some unsigned value here
....

for(uCount = 0; uCount < uMaxVal -1; uCount++)
{

 //Do whatever
}


Do you find anything wrong on seeing this simple statements? You thinks the loop will terminates when the uCount value reaches the uMaxVal.


What if uMaxVal value is 0.

You simply says the program control will not enter in to the for loop. But it is false.

What is the value of (nMaxVal -1) when nMaxVal is equals to zero.

If you Answer '-1' it is Wrong.

Since it is a Unsigned Long value, it does not return -1, instead it returns the maximum value of the long datatype. For a 32 bit compiler it returns '4294967295' as a results. So the program control enters into the for loop and it iterates until uCount reaches the maximum value.

So, beware of using unsigned values.

This is not an infinte loop bug, it terminates once the max value  but the behavior of the program is undefined.

Wednesday, June 29, 2011

Visual Studio 2010 IDE Hangs when menu items are activated

Sometimes, When mouse over the main menu items (File, Edit, View … Window or Help), the IDE hangs. Sometimes, when clicking on the menu item it will highlight or turn completely black.

The same happens when using the keyboard. Alt+F highlights the File menu. Sometimes (after a few seconds) the region that should display the menu will be drawn in a solid color, but the menu is not populated.

On rare occasion (when using the mouse), the menu will populate, but when hovering over a sub-menu item, the item blinks – or is completely erased.


Environment:
I just upgraded from XP to Win7 Enterprise. Installed VS 2010 Premium and SP1.

Attempted Resolution:
devenv.exe /safemode – It happens when VS is running in Safe Mode also.
I have disable Aero – still happens.
Disabled Hardware acceleration via registry: HKEY_CURRENT_USER\SOFTWARE\Microsoft\Avalon.Graphics\DisableHWAcceleration
Have uninstalled and reinstalled Visual Studio and the service pack.

Visual Studio worked properly when I booted the machine in safe mode. (So I assumed there were some conflicts with in one of the many drivers I installed.)

While in Windows -Safe Mode-, I went to Tools->Options. On the options window, under Environment: General I changed the 'Visual experience' settings. I unchecked "Automatically adjust visual experience based on client performance", "Enable rich client visual experience" & "Use hardware graphics acceleration if available".

With these settings, the IDE works perfectly!

Problem resolved.

More info at https://connect.microsoft.com/VisualStudio/feedback/details/675328/vs2010-ide-hangs-when-menu-items-are-activated