2

我将保持简短明了 - 为了练习动态分配的内存,我决定制作一个圆圈,我将在其中将它的参数(中心的 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;
}
4

2 回答 2

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;
}

在实现赋值运算符时,请考虑复制和交换习语

于 2013-05-25T06:23:02.320 回答
-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;
}
于 2013-05-25T06:30:35.990 回答