Assume a class named MySTring, with a member named data, that represents a C-style string, enforces conditions that data cannot be NULL (i.e. MyString never contains a NULL pointer), and the data member is guaranteed to be non-NULL.
This assignment operator implements the strong exception safety guarantee. The reasoning for that statement;
MyString &operator=(const MyString &c)
temp = new char[strlen(c.data) + 1];
delete  data;
data = temp;
1) The only line of code that can throw an exception is the first line, as strcpy() does not throw, operator delete does not throw, and simple pointer assignment does not throw. If the allocation in the first line fails, an exception is thrown, and the object (the left hand side of the assignment) is unchanged.
2) The data member is not deleted unless a new buffer has been successfully allocated and copied to.
3) Returning a reference to an existing object does not throw.
4) This operator does not attempt to change the right hand side of the assignment (i.e. argument c).
The key in doing this is to define an invariant (a set of pre-conditions that are always satisfied on calling any public member function, and which are not violated when that function returns) for the class. Hence the assumptions I gave before presenting the example.
And, yes, this example could be implemented using a temporary MyString and a swap() function. Different techniques are not necessarily mutually exclusive.