C++ Copy Constructor и Exceptions Handling
Ниже приведен очень простой пример того как работает copy constructor:
class Base
{
public:
Base() { std::cout << "Base default constructor invoked!" << std::endl; };
Base(const Base& copy) { std::cout << "Base copy constructor invoked!" << std::endl; };
Base& operator=(const Base& copy) = default;
};
class Derived : public Base
{
public:
Derived() { std::cout << "Derived default constructor invoked!" << std::endl; }
Derived(const Derived& copy) { std::cout << "Derived copy constuctor invoked!" << std::endl; }
};
int main(void)
{
Derived der;
Derived der0 = der;
return 0;
}
И если в функции main изменить Derived der0, на Derived& der0, то copy constructor не будет вызван.
Отсюда появляется вопрос, почему когда мы отлавливаем исключения по ссылке:
try
{
// throw error
}
catch(std::exception& e) {}
Тогда у нас будет вызван конструктор копирования и при этом только для класса exception?
Почему в обычной ситуации у нас (как в примере выше) не вызывается никакой конструктор копирования для класса Base когда мы выполняем Derived& der0 = der, но в блоке catch он вызывается, при этом только для исключения самого верхнего уровня?
Пример того как это работает, но без объяснения нашел здесь.
Ответы (1 шт):
На ссылке, что вы скинули рассматривается передача аргументов по значению и по ссылке на константный объект. В вашем примере вы показываете ссылку на действительный (имеющий адрес) объект (не константный). Ваш пример не такой.
Аргументы функций вида const & принимают объекты любого типа (на временные или действительные). К конструктору копирования не имеют никакого отношения.
void f(int const & x) {
... }
void h(int & x) {
... }
void g(void){
int x = 10 ;
f(x); // Ok
h(x); // Ok
f(int(7.5)); // Ok
h(int(7.5));
// error: cannot bind non-const lvalue reference of type ‘int&’ to an rvalue of type ‘int’
}