复制构造函数和动态分配的数组

时间:2013-05-25 06:16:06

标签: c++ memory dynamic

我会保持简短明了 - 为了练习动态分配的内存,我决定制作一个圆圈,在其中我将它的参数(中心的X和Y以及半径长度)存储在一个动态分配的数组中。由于数组是动态分配的,这意味着为了阻止泄漏,我必须实现一个构造函数。这也意味着为了避免其他一些错误,我需要实现一个复制构造函数并重载赋值运算符。 (几乎相同的代码)我认为我已经相当好地实现了析构函数。不过,我确实需要一些关于复制构造函数的帮助。

#include <iostream>

using namespace std;

class Circle
{
private:
    int* data;
public:
    Circle(){
        cout <<"I am the default constructor" << endl;
        data = NULL;
    }
    Circle(int* p){
        cout <<"I am the set up constructor" << endl;
        data = p;
    }
    ~Circle(){
        cout <<"I am the destructor" << endl;
        delete data;
    }
    Circle& operator=(const Circle& tt1){
        cout << "Overloaded assignment operator reporting in!" << endl;
        if(this != &tt1){
            //free old data
            delete this->data;
            data = new int(3);
           *data = *(tt1.get_data());
            *(arr+1) = *(tt1->get_data()+1);
            *(arr+2) = *(tt1->get_data()+2);
            return *this;
        }
    }
    Circle(const Circle& tt1){
        cout << "I am the copy constructor!" << endl;
        if(this != &tt1){
            //free old data
            delete this->data;
            data = new int(3);
           *data = *(tt1.get_data());
            *(arr+1) = *(tt1->get_data()+1);
            *(arr+2) = *(tt1->get_data()+2);
            return *this;
        }
    }
};

int main(){
    //is this object constructed well?
    int arr [] = { 16, 2, 7};
    Circle a(arr);

    return 0;
}

2 个答案:

答案 0 :(得分:4)

//is this object constructed well?
int arr [] = { 16, 2, 7};
Circle a(arr);

答案是“是和否”:您的构造函数不会复制数组,只是将指针复制到数组的第一个元素。因此,如果您不希望您的Circle类拥有该数组,则不需要提供析构函数,复制构造函数或赋值运算符。

但是你更有可能希望你的类拥有数组,在这种情况下你需要制作它的本地副本并存储它。为了实现这一点,你需要一条额外的信息:数组的大小,当传递给(并实现析构函数,复制构造函数,赋值运算符)一个带指针的函数时,它完全丢失。

编辑,因为这是动态分配的练习,在输入数组总是大小为3的情况下,这是一个构造函数采用数组的示例:

Circle(int* p)
{
  data = new int[3];
  std::copy(p, p+3, data); // UB if p doesn't point to an array of at least 3 elements
}

您需要在析构函数中调用delete[],因为您调用了new[]

~Circle()
{
    delete [] data;
}

实现赋值运算符时,请考虑copy and swap idiom

答案 1 :(得分:-2)

我写了一个关于你的练习的正确代码,我希望这可以帮助你。我用tdm-gcc构建它并运行良好。

#include<iostream>
#include<algorithm> //std::copy
using namespace std;

class Circle {
private:
 int* data;

public:
 Circle(){
  cout <<"I am the default constructor" << endl;
  data = NULL;
 }

 Circle(int* p){
  cout <<"I am the set up constructor" << endl;
  data =new int[3];
  copy(p,p+3,data);
 }

 ~Circle(){
  cout <<"I am the destructor" << endl;
  if (data!=NULL) {
   delete[] data;
  }
 }

 Circle(const Circle& tt1){
  cout << "I am the copy constructor!" << endl;
  if (this != &tt1) {
   if (data!=NULL) {
    delete[] data;
   }

   data = new int[3];
   *data = *(tt1.get_data());
   *(data+1) = *(tt1.get_data()+1);
   *(data+2) = *(tt1.get_data()+2);
  }
 }

 Circle& operator=(const Circle& tt1){
  cout << "Overloaded assignment operator reporting in!" << endl;
  if (this != &tt1) {
   if (data!=NULL) {
    delete[] data;
   }
   data = new int[3];
   *data = *(tt1.get_data());
   *(data+1) = *(tt1.get_data()+1);
   *(data+2) = *(tt1.get_data()+2);
  }
 }

 int* get_data() const {
  return data;
 }
};

int main(){
 int arr[]={16,2,7};
 Circle a(arr);
 cout<<*a.get_data()<<'\t'
 <<*(a.get_data()+1)<<'\t'
 <<*(a.get_data()+2)<<endl<<endl;

 return 0;
}