У меня есть вспомогательный класс для освобождения дескрипторов MYSQL_RES.
class auto_mysqlres
{
public:
auto_mysqlres(MYSQL_RES *res) : m_res(res)
{
}
~auto_mysqlres()
{
if (m_res != NULL)
mysql_free_result(m_res);
}
operator MYSQL_RES* ()
{
return m_res;
}
private:
auto_mysqlres& operator= (const auto_mysqlres &res);
auto_mysqlres (const auto_mysqlres &res);
private:
MYSQL_RES *m_res;
};
когда я пытаюсь использовать это таким образом
auto_mysqlres result = return_pointer_to_mysql_res();
Я получаю ошибку в GCC 4.6.3: auto_mysqlres::auto_mysqlres(const auto_mysqlres&) is private
, ошибок в MSVC 2008 нет.
return_pointer_to_mysql_res
возвращается MYSQL_RES*
, конечно
Я исправил проблему с этой линией auto_mysqlres result (return_pointer_to_mysql_res());
но я хочу выяснить, почему я получаю эту ошибку. Я не могу понять, почему GCC создает временный объект там.
Вы выполняете инициализация копии Вот:
auto_mysqlres result = return_pointer_to_mysql_res();
Это требует доступности конструктора копирования, даже если копии удаляются. Семантически, вы строите временный auto_mysqlres
от указателя на RHS, и скопируйте конструкцию из него на LHS.
Ты можешь использовать прямая инициализация вместо:
auto_mysqlres result(return_pointer_to_mysql_res());
увидеть больше на скопируйте инициализацию и прямую инициализацию здесь.
Как указывает @Rapptz в комментарии, в C ++ 11 вы можете решить сделать ваш класс перемещаемым копируемым (и, возможно, перемещаемым назначаемым), и в этом случае конструктор перемещения копии будет выбран при инициализации копии.
Хорошо .. @myself: Обучение никогда не останавливается. 🙂
Ваш конструктор не является явным и, следовательно, способ неявного преобразования MYSQL_RES*
в качестве auto_mysqlres
, Это то, что gcc делает здесь. Преобразует MYSQL_RES*
в auto_mysqlres
а затем пытается вызвать конструктор копирования. Это необходимо здесь.
Инициализация, которая происходит в форме
[…] называется copy-initialization.
- Т х = а;
Вы копируете-инициализируете свой объект.
[… Если инициализация] является копией-инициализацией, где cv-неквалифицированная версия исходного типа является тем же классом, или производным классом класса назначения, учитываются конструкторы. […]В противном случае (т.е. для остальных случаев инициализации копирования), определяемые пользователем последовательности преобразования, которые могут преобразовывать тип источника в тип назначения или (если используется функция преобразования) в производный класс, перечисляются, как описано в 13.3.1.4, и лучшая из них выбирается с помощью разрешения перегрузки. ,
В твоем случае MYSQL_RES*
не совпадает с классом или производным классом класса назначения (auto_mysqlres
) поэтому требуется преобразование, поскольку конструктор не рассматривается.
Вы либо
должны сделать прямую инициализацию
auto_mysqlres result(return_pointer_to_mysql_res());
или предоставить (переместить) конструктор копирования.
PS: не совсем знал where the cv-unqualified version of the source type is the same class as, or a derived class of, the class of the destination
,