关于C ++ OOP数组成员复制行为

时间:2014-01-03 00:40:53

标签: c++ arrays oop member

我知道这可能听起来微不足道,但我是C ++ OOP的新手。非常感谢您的帮助!

例如,对于以下代码:

using namespace std;

class Object {
public:
    int arr[10];
    Object(int b) {memset(arr, 0, sizeof(arr));}
};

void test(Object &first, Object other)
{
    cout << "Test" << endl;
    cout << (first.arr) << endl;
    cout << (other.arr) << endl;
    return;
}

int main() 
{
    Object x(2);
    Object y(3);
    test(x, y);
    return 0;
}

请注意,在函数声明void test(Object &first, Object other)中,第一个参数采用原始别名,而第二个参数采用副本。

我知道Object other创建了传递给此函数的对象的本地副本。但问题是:成员arr是否也被复制了?换句话说,当调用test(x, y) y.arrother.arr指向相同或不同的数组时?

如果执行了复制,它是执行浅拷贝还是深拷贝?

如果不是声明int arr[10],而是使用int *arr并使用arr关键字在构造函数中动态分配new,那么会是什么情况呢? / p>

非常感谢!

编辑:我的发现

在声明int arr[10]的情况下,是否复制了一个新数组,并且新数组中的元素指向原始数组中的对象?

当使用new关键字来动态分配时,复制的数组仍然是指向复制对象数组的指针?

1 个答案:

答案 0 :(得分:2)

默认的复制构造函数执行成员明智的复制(感谢Yuri,其下面的注释澄清了这一点,因为我最初说的是按位复制)。您可以通过更改构造函数并为Object提供输出运算符来更清楚地看到这一点:

#include <algorithm> // for fill()
using namespace std;

class Object {
  private:
    int arr[10];
  public:
    Object(int i=0);
    friend ostream& operator<<(ostream& ostr, const Object& obj);
};

Object::Object(int i)
{
  fill(arr, arr + 10, i); 
}

ostream& operator<<(ostream& ostr, const Object& obj)
{
   ostr << "outputting member 'int arr[10]' of size " << sizeof(obj.arr)/sizeof(int) << "\n";

   for (int i = 0; i < sizeof(obj.arr)/sizeof(int); i++)  {

        ostr << obj.arr[i] << ", ";

   } 
   ostr << "\n";
   return ostr;
}

void test(Object &first, Object other)
{
    cout << "Test" << endl;
    cout << first << endl;
    cout << other << endl;
    return;
}

int main(int argc, char** argv) 
{
 Object x(4);
 Object y(x);

 test(x, y);
 return 0;
}

“那么在不使用int arr [10]而是使用int * arr并使用new关键字在构造函数中动态分配arr的情况下是什么情况呢?”

在这种情况下,两个对象都将指向相同的地址,这意味着y可以更改动态分配的x数组,反之亦然。可能不是你想要的。因此,您需要提供一个复制构造函数来避免这种情况:

#include <algorithm> // for fill()
using namespace std;

class Object {
  private:
    int *p;
  public:
    Object(int i=0);
    Object(const Object& rhs);
    ~Object();
    friend ostream& operator<<(ostream& ostr, const Object& obj);
};

Object::Object(int i)
{
  p = new int[10];  
  fill(p, p + 10, i); 
}
Object::Object(const Object& rhs)
{
   p = new int[10];
   for(int i = 0; i < 10; i++) {
        p[i] = rhs.p[i];
    }    
}

Object::~Object()
{
      delete [] p;
}  

ostream& operator<<(ostream& ostr, const Object& obj)
{                 
   for (int i = 0; i < 10; i++)  {
            ostr << obj.p[i] << ", ";
   } 
   ostr << "\n";
   return ostr;
}

void test(Object &first, Object other)
{
    cout << "Test" << endl;
    cout << first << endl;
    cout << other << endl;
    return;
}

int main(int argc, char** argv) 
{

    Object x(4);
    cout << x << endl;
    Object y(5);
    test(x, y);
    return 0;
}