为什么我需要在这里复制构造函数
why do I need copy constructor here
我有一个助手类用于释放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();
这需要有一个副本构造函数可用,即使副本已被删除。从语义上讲,您正在从RHS上的指针构造一个临时auto_mysqlres
,并在LHS上从它复制构造。
您可以使用直接初始化:
auto_mysqlres result(return_pointer_to_mysql_res());
请在此处查看有关复制初始化和直接初始化的更多信息。
正如@Rapptz在一条评论中指出的那样,在C++11中,您可以决定使类移动可复制(并且可能移动可赋值),在这种情况下,移动-复制构造函数将在复制初始化中使用。
嗯@我自己:学习永无止境
您的构造函数不是显式的,因此是将MYSQL_RES*
隐式转换为auto_mysqlres
的一种方法。这就是gcc在这里所做的。它将MYSQL_RES*
转换为auto_mysqlres
,然后尝试调用复制构造函数。这是必需的。
§8.5[dcl.init]/14
以形式发生的初始化
- T x=a
[…]称为复制初始化。
您复制并初始化您的对象。
§8.5[dcl.init]/16
[…如果初始化]是复制初始化,其中源类型的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
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 当从函数参数中的临时值调用复制构造函数时
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 为什么类中的ostringstream类型的成员会导致";调用隐含删除复制构造函数";错误
- 复制构造函数、赋值运算符C++
- std::ofstream 作为类成员删除复制构造函数?
- 复制构造函数C++无法正确复制指针
- 关于复制构造函数的一个棘手问题
- 为什么调用复制构造函数而不是移动构造函数?
- 填充上编译器生成的复制构造函数之间的不一致
- C++ 对象指针数组的复制构造函数
- C++ 基本 CTOR 说明 - 为什么不调用赋值/复制构造函数
- 防止在复制构造函数中隐式调用基构造函数
- 为用户定义的类正确调用复制构造函数/赋值运算符
- 具有已删除移动和复制构造函数的类的就地构造
- 复制构造函数隐式转换问题
- 复制构造函数中的递归调用