繁体   English   中英

为什么我在这里需要复制构造函数

[英]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得到错误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());的问题auto_mysqlres result (return_pointer_to_mysql_res());

但我想知道为什么我会收到这个错误。 我无法理解为什么GCC在那里创建一个临时对象。

您正在执行复制初始化

auto_mysqlres result = return_pointer_to_mysql_res();

这要求复制构造函数可用,即使复制被省略也是如此。 从语义auto_mysqlres ,您是从RHS上的指针构造临时auto_mysqlres ,并在LHS上从中复制构造。

您可以使用直接初始化

auto_mysqlres result(return_pointer_to_mysql_res());

这里查看有关复制初始化和直接初始化的更多信息

正如@Rapptz在评论中指出的那样,在C ++ 11中,您可以决定让您的类移动可复制(并且可能移动可分配),在这种情况下,移动复制构造函数将在复制初始化中被拾取。

嗯.. @myself:学习永不停止。 :)

您的构造函数不是显式的,因此可以将auto_mysqlres MYSQL_RES*隐式转换为auto_mysqlres 这就是gcc在这里所做的。 它将auto_mysqlres MYSQL_RES*转换为auto_mysqlres ,然后尝试调用复制构造函数。 这是必需的。

§8.5[dcl.init] / 14

在表单中发生的初始化

  • T x = a;

[...]称为复制初始化。

您复制 - 初始化您的对象。

§8.5[dcl.init] / 16

[...如果初始化]是复制初始化,其中源类型的cv-nonqualified版本与目标类的类相同,或者是派生类,则考虑构造函数。 [...]

否则(即, 对于剩余的复制初始化情况 ),可以如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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM