何时使用复制构造函数?

时间:2015-05-15 05:25:49

标签: c++ constructor

我创建了一个类,它有一个带参数的构造函数。我是否认为我需要一个复制构造函数?

我有一个类,它没有指针:

if ($.hasFun(myFunc)) {
    $('selector').myFunc();
}

基地:

class xyz : public Node
{
public:
    xyz( uint8_t node);
    xyz(const xyz& cxyz);
    ~xyz();

private:
    uint8_t m_node;
    uint16_t m_gainxyz;

当我这样做时:

class Node
{
public:

Node();
virtual ~Node();

protected:
    std::string  m_name;

编译器告诉我创建一个复制构造函数。

其中:

xyz xyz = Initxyz(node);

但根据我在网上看到的内容:

  

如果对象没有指向动态分配内存的指针,则浅拷贝可能就足够了。因此,默认的复制构造函数,默认赋值运算符和默认析构函数都可以,您不需要编写自己的。

http://www.fredosaurus.com/notes-cpp/oop-condestructors/copyconstructors.html

如果我使用带参数的构造函数,我必须有一个吗?

4 个答案:

答案 0 :(得分:0)

我将提供一些规范性参考,以便正式解释这件事。

如果我正确理解了您想要的内容,那么当您需要制作对象的副本时N4296::12.8/1 [class.copy]

  

可以通过两种方式复制或移动类对象:通过初始化   (12.1,8.5),包括函数参数传递(5.2.2)和for   函数值返回(6.6.3);并通过转让(5.18)。

实际上,复制构造函数可能被隐式声明为已删除,因此如果您在需要复制时尝试调用它,则会给出编译时错误。

相关参考:

  

隐式声明的复制/移动构造函数是内联公共   同类的成员。 X类的默认复制/移动构造函数   如果X有:

,则定义为已删除(8.4.3)      

(11.1) - 具有非平凡对应构造函数的变体成员   和X是一个类似联合的类,

     

(11.2) - 可能构建的   子对象类型M(或其数组),无法复制/移动   因为重载决议(13.3),适用于M的相应   构造函数,导致歧义或被删除的函数或   默认构造函数无法访问,

     

(11.3) - 任何潜在的   构造了一个带有析构函数的类型的子对象,该析构函数被删除或   默认构造函数无法访问,或

     

(11.4) - 副本   构造函数,rvalue引用类型的非静态数据成员。

可能构建的子对象定义如下N4296::12/5

  

对于一个类,它的非静态数据成员,它的非虚拟直接基础   类,如果类不是抽象的(10.4),它的虚拟基础   类被称为可能构建的子对象

答案 1 :(得分:0)

  

我创建了一个类,它有一个带参数的构造函数。我是否认为我需要一个复制构造函数?

需要为您的类提供复制构造函数。编译器生成的就足够了。

以下是a working example based on your code

#include <iostream>
#include <string>
#include <stdint.h>

class Node
{
public:

  Node() {}
  virtual ~Node() {}

protected:
  std::string  m_name;
};

class xyz : public Node
{
public:
    xyz( uint8_t node) {}

private:
    uint8_t m_node;
    uint16_t m_gainxyz;
};

xyz Initxyz(Node)
{
    return xyz(42);
}

int main()
{
    Node node;
    xyz xyz = Initxyz(node);
}

答案 2 :(得分:0)

当您想要进行深拷贝而不是浅拷贝时,需要复制构造函数。这意味着您正在避免悬空指针问题。 实际上编译器也提供了默认的拷贝构造函数,但是如果你不是用于拷贝的构造函数的任何字符串,它就可以正常工作。 但是如果你想将字符串从一个类的对象复制到类的其他对象,那么你不能将一个内存地址引用到两个指针。 尝试做复制构造函数的例子。

答案 3 :(得分:-1)

复制构造函数

复制构造函数用于:

  • 在创建时初始化对象(我们想要创建一个 具有现有对象状态的对象)
  • 当一个对象通过值传递给一个函数时(如您所知) 在堆栈上创建对象的临时副本,因此我们需要复制 构造函数用于创建具有实际状态的临时对象 对象被传递。。

我们需要Copy构造函数从其他对象初始化一个对象,通常我们使用赋值运算符来调用复制构造函数。 以下是更多理解的示例。

class Student{ 
      int rollNo; 
public: 
    Student(){ 
       rollNo = 0; 
       cout<<"I am default constructor of Student class…\n";  
    } 
    Student(const Student &obj){ 
     cout<<"I am copy constructor of Student class\n";  
     rollNo = obj.rollNo; 
    } 
}; 
int main() 
{ 
    Student aStudent;  /*default constructor is implicitly called at this point*/ 
    Student bStudent = aStudent;    /*copy constructor is implicitly called at this point, 
                                   because of the here we are going to initialize one object 
                                   from other previously existing object. */
}