Для на чала надо выяснить один принципиальный вопрос из-за которого возможна полная лажа в дискуссии, так вот собственно сам вопрос в твоем примере 
#include <iostream.h> 
class CErrors{
public: 
virtual void PrintError()=0; 
}; 
class COutMemory: public CError{
public: 
virtual void PrintError() {cout<<"COutMemory";}
}
class COutRange: public CError{
public: 
virtual void PrintError() {cout<<"COutRange";}
}; 
void Func(){
throw COutRange(); 
}
int main(){
try{
Func(); 
}
catch(CError& error){
error.PrintError(); 
}
return 0; 
}
НЕТ сласса CError!!! если это просто опечатка и CErrors = CError то продолжаем разговор... 
ты писал 
Класс COutOfMemory является производным от CError. Я не знаком с термином "срезание объекта", но судя по всему ты имеешь ввиду процедуру приведения типа указателя производного класса к типу указателя на бозовый класс. Благодаря этому через этот указатель будет виден только фрагмент базового класса, а фрагмент производного класса окажется невиден. Т.е вот так: 
static_cast <CError*> (COutOfMemory*);
Если я правильно тебя понял это и обозначает термин "срезание"... 
Нет ты понял не правильно, срезание объекта это следующее (кстати при использовании указателей или ссылок срезания полиморфных объектов НЕ происходит, оно и понятно веть имея поинтер на базовый класс и вызывая виртуальную функцию... вызовется функция того объекта который реально был создан, т.е. если был создан объект производного класс то и вызовется функция производного класса (еще раз обращу внимание это при условии что поинтер то был на БАЗОВЫЙ) - это просто описание работы виртуальных функций), продолжим про срезание... так вот .. этот код 
throw COutOfMemory(); 
... 
catch(CErrors error) 
{
error.ShowError(); 
}
эквивалентен следующему В ПЛАНЕ СРЕЗАНИЯ (а не времени жизни объектов) 
COutOfMemory outOfMemory(); 
CError error(outOfMemory); // вот здесь и происходит срезание т.к. объект error
              // имеет тип CError и ничего об COutOfMemory не знает в том числе
              // и то что функция ShowError() объеска error никакого сообщения
              //НЕ выдает, отсюда и термин срезание... т.е. мы срезали объект
              // с типом COutOfMemory (и функционалом объекта типа COutOfMemory),
              // до типа CError (и соответственно функционалом объекта типа CError) 
... 
catch(CErrors  &  error) // здесь ссылка для того чтобы не создавать ЕЩЕ один
                                    // временнный объект 
{
error.ShowError(); 
}
идем дальше 
throw COutOfMemory(); 
... 
catch(CErrors error) 
{
error.ShowError(); 
}
Тут не много другая история... 
Сначала создаётся объект-исключение ( throw COutOfMemory(); ). Т.к в блоке catch объявлена не ссылка и не указатель, а именно переменна с типом класс, то происходит создание ещё одного объекта, но на этот раз базового класса. Таким образом в стеке уже два объекта. 
Абсолютно верно, я же именно это и написал вот смотри 
если рассмотреть второй вариант 
throw COutOfMemory(); 
... 
catch(CErrors error) 
{
error.ShowError(); 
}
то тут сначала создается на стеке объект типа COutOfMemory (вот туточки создается throw COutOfMemory(); ) ...... 
и далее
....... 
тогда в catch происходит создание стекового объекта типа CErrors (с вызовом копирующего конструктора) 
....... 
 Это 
Далее происходит срезание объекта производного класса (того которым бросались тут - throw COutOfMemory(); ) и копирование его при помощи конструктора копирования в объект который был создан тут catch(CErrors error) ... Область видимости этого объекта - блок catch(...) - это ясно. Т.е когда будет выполнен выход из блока catch(...) то этот экземпляр будет автоматически разрушен вызовом его деструктора 
 тоже верно я и об этом написал смотри мой предыдущий ответ, а теперь по поводу этого 
а какая область видимости будет у объекта созданного throw COutOfMemory(); ? - сколько он будет висеть в стеке? Предполагаю, что до тех пор, пок не будет выполнено завершение подпрограммы которя бросала исключение. 
 тоже не верная догадка, вот смотри это 
throw COutOfMemory(); 
эквивалентно (в плане жизни объектка) следующему 
printf(std::string("bubu").c_str()); 
спрашивается как же долго будет жить стековый объект типа std::string, а ответ такой, ооочень не долго и по выполнению функции printf он уничтожится, то же самое и утебя после обработки исключения т.е. вот этого 
т.е. после выполнения этого блока сначала уничножится объект типа CError, а потом сразу за ним уничножится объект типа COutOfMemory,кстати я и об этом писал вот 
...
затем опять после вызова error.ShowError(); после закрытия } удаляется САМ временный (стековый) объект типа CErrors, а потом опять же САМ удаляется стековый объест типа COutOfMemory
...
по поводу этого 
И последнее: 
ну и наконец третий вариант 
throw new COutOfMemory(); 
... 
catch(CErrors * error) 
{
error->ShowError(); 
delete error; 
}
тут у нас для начала создаетя в КУЧЕ!!!! объект типа COutOfMemory, далее мы бросаемся этим самым объектом потом ловим его и тут уже естественно надо его замочить потому как память отожрана. 
Я думаю, что в этом случае, вместо 
бросаемся этим самым объектом 
правильно будет говорить: 
"бросаемся указателем на этот самый объект" 
могу сказать следующее, что не знаю как правильно сказать (объект или указатель) но смысл был именно в этом