简体   繁体   English

指针向量的C ++复制构造函数

[英]C++ Copy constructor for a pointer to vector of pointers

I have a class A , which has as a member a pointer to a vector of pointers ( current ), the vector which contains a pair of an integer and an object of class B . 我有一个类A ,该类具有一个指向向量指针的指针( current ),该向量包含一对整数和一个B类对象。 I need to be able to create copies for objects of class A , and for that I use a Clone function (see code below). 我需要能够为AA对象创建副本,为此,我使用了Clone函数(请参见下面的代码)。 However, when I use this function, the pointers seem to be pointing to the same memory location, instead of different ones. 但是,当我使用此功能时,指针似乎指向相同的内存位置,而不是指向不同的位置。 I think the solution to this is to implement a copy constructor for my class in order to be able to properly copy my objects, but I am failing to do so. 我认为解决此问题的方法是为我的类实现一个复制构造函数,以便能够正确复制我的对象,但是我没有这样做。

Here is how my class looks like and the several tries I had for implementing the copy constructor: 这是我的类的样子,以及为实现复制构造函数而进行的几次尝试:

class A {
public:
    A();
    A(const A &a);
    ~A();
    A* Clone() {return new A(*this);}
    std::vector<std::pair<unsigned int, B*>> *current;
};

EDIT: The constructor and destructor are implemented as follows: 编辑:构造函数和析构函数的实现如下:

A::A() {
    current = new vector<std::pair<unsigned int, B*>>;
}

A::~A() {
    std::vector<std::pair<unsigned int, B*>>::iterator cit = current->begin(), cend = current->end();
    for (; cit != cend; ++cit) {
        delete cit->second;
    }
    delete current;
}

Option #1: 选项1:

A::A(const A &a){
    *current = *a.current;
}

Option #2: 选项2:

A::A(const A &a){
    for(int i = 0; i < current->size(); i++) {
        (*current)[i] = (*a.current)[i];
    }
}

Option #3: 选项3:

A::A(const A &a){
    for(int i = 0; i < current->size(); i++) {
        (*current)[i].first = (*a.current)[i].first;
        (*current)[i].second = new B((*a.current)[i].second);
    }
}

Options #1 and #2 give me segmentation fault, while for #3 I get the error: no match for operator * 选项#1和#2给我分段错误,而对于#3,我得到了错误: no match for operator *

Which is the correct way to implement the copy constructor and also should my Clone function be implemented differently? 哪个是实现复制构造函数的正确方法,我的Clone函数应该以不同的方式实现吗?

Your constructor does not initialise the current member at all. 您的构造函数根本不初始化current成员。 In any of the options. 在任何选项中。

From there, accessing its value (ie the value of the pointer named current ) gives undefined behaviour. 从那里,访问它的值(即,名为current的指针的值)会产生不确定的行为。 And so does dereferencing it. 取消引用也是如此。 The usages of *current or *a.current in all options (and variations therefore) therefore ALL give undefined behaviour. 因此,在所有选项(及其变体)中使用*current*a.current都会产生不确定的行为。

If you insist that the member current must be a pointer, it must be initialised in ALL constructors. 如果您坚持成员current必须是一个指针,则必须在ALL构造函数中对其进行初始化。 For example, the constructor A::A() (which you haven't shown) must look something like 例如,构造函数A::A() (未显示)必须看起来像

 A::A() : current(new std::vector<std::pair<unsigned int, B*>>(0))
 {
     //   initialised current with no elements
     // add pairs to the vector

     current->push_back(std::make_pair(0U, new B));
     current->push_back(std::make_pair(42U, new B));
 }

and the copy constructor must start with something akin to 复制构造函数必须以类似于

A::A(const A &a) : current (new std::vector<std::pair<unsigned int, B *>>(a.current->size())
{
    for(int i = 0; i < current->size(); i++)
    {
        (*current)[i].first = (*(a.current))[i].first;
        (*current)[i].second = new B((*(a.current))[i].second);
    }
}

More generally, however, there is actually no reason for current to be a pointer created using operator new . 但是,更一般而言,实际上没有理由使current是使用运算符new创建的指针。 In that case the constructors could be simplified to 在那种情况下,构造函数可以简化为

 A::A() : current(0)
 {
     // add pairs to the vector

     current.push_back(std::make_pair(0U, new B));
     current.push_back(std::make_pair(42U, new B));
 }

and the copy constructor to 和复制构造函数到

A::A(const A &a) : current (a.current.size())
{
    for(int i = 0; i < current.size(); i++)
    {
        current[i].first = a.current[i].first;
        current[i].second = new B(a.current[i].second);
    }
}

You've also provided no compelling information to suggest that current needs to be vector<pair<unsigned, B *>> rather than vector<pair<unsigned, B>> . 您也没有提供任何令人信服的信息来建议current必须是vector<pair<unsigned, B *>>而不是vector<pair<unsigned, B>> If the vector doesn't need to hold pointers (ie it holds objects directly) then, practically, you will not need to define the copy constructor at all - the compiler-generated default will suffice. 如果向量不需要保留指针(即直接保留对象),那么实际上,您根本不需要定义复制构造函数-编译器生成的默认值就足够了。 And your code will not need to use operator new at all (except, possibly, in A::Clone() ). 而且您的代码根本不需要使用new运算符(可能在A::Clone()除外)。

Note that, if you do actually need to hand-roll a copy constructor, you will probably need to also hand-roll an operator=() and a destructor. 请注意,如果确实需要手动滚动副本构造函数,则可能还需要手动滚动一个operator=()和一个析构函数。 Look up "rule of three" (before C++11) or (C++11 and later) "rule of five" and "rule of zero" for more information. 查找“三个规则”(在C ++ 11之前)或(C ++ 11及更高版本)“五个规则”和“零规则”以获取更多信息。

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

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