Рассмотрим этот фрагмент кода:
#include <vector>
#include <iostream>
using namespace std;
class Base
{
char _type;
public:
Base(char type):
_type(type)
{}
~Base() {
cout << "Base destructor: " << _type << endl;
}
};
class uncopyable
{
protected:
uncopyable() {}
~uncopyable() {}
private:
uncopyable( const uncopyable& );
const uncopyable& operator=( const uncopyable& );
};
class Child : public Base, private uncopyable
{
int j;
public:
Child():
Base('c')
{}
~Child() {
cout << "Child destructor" << endl;
}
};
int main()
{
vector<Base> v;
Base b('b');
Child c;
v.push_back(b);
v.push_back(c);
return 0;
}
Вывод в моей системе:
Base destructor: b
Child destructor
Base destructor: c
Base destructor: b
Base destructor: b
Base destructor: c
Мои вопросы:
Почему деструктор Base
(с типом b) вызывается три раза вместо двух (у нас больше двух копий объекта b)?
Что происходит, когда мы копируем объект типа Child
, учитывая, что копирующий конструктор одного из его родителей является закрытым. Это неопределенное поведение?
Я ожидал получить ошибку времени компиляции при каждой попытке скопировать объект типа Child
. Я думал, что дочерний конструктор копирования по умолчанию попытается вызвать закрытый конструктор копирования класса Uncopyable и вызвать ошибку компиляции. Почему не выдает ошибок компиляции?
Код разработан таким образом потому, что класс Child
огромен.
Желаемое поведение — отбрасывать дочерние данные всякий раз, когда клиент пытается скопировать объект Child
(вызывая деструктор Child
без вызова деструктора Base
. ]).
Этот фрагмент кода достигает этого, но я предполагаю, что это приводит к неопределенному поведению и утечке памяти (никогда не вызывает деструктор Child
для скопированного экземпляра).