3

I know this may sound trivial, but I'm new to C++ OOP. Thanks a lot for help!

For example, for the following code:

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

Note that in the function declaration void test(Object &first, Object other), the first parameter takes the original alias, while the second takes a copy.

I'm aware that Object other creates a local copy of the object passed into this function. But question is: is the member arr copied as well? In other words, when calling test(x, y) does y.arr and other.arr point to the same or different array?

If a copy is performed, does it perform shallow or deep copy?

What then is the case when instead of declaring int arr[10], a int *arr is used and the arr is dynamically allocated in the constructor, using the new keyword?

Thanks a lot!

Edit: My findings

Is it that in the case of declaring int arr[10], a new array is copied, and the elements inside the new array point to the objects in the original array?

When instead new keyword is used to dynamically allocate, the copied array is still a pointer to the array of the copied object?

lwxted
  • 2,419
  • 2
  • 16
  • 22
  • 2
    You went to the trouble of writing most of the code needed to find the answer for yourself; wouldn't it be more satisfying to finish the job? – Scott Hunter Jan 03 '14 at 00:47
  • To be honest, I'm seeking a confirmation to my findings: Is it that while a new array is copied, the elements inside the array point to the objects in the original array? When instead `new` is used to dynamically allocate, the array is still a pointer to the array of the copied object? – lwxted Jan 03 '14 at 00:47
  • Post does not appear to have been edited; what were your findings? – Scott Hunter Jan 03 '14 at 00:50
  • Please see the comment above, thanks. – lwxted Jan 03 '14 at 00:51
  • Does this answer your question: http://stackoverflow.com/questions/4164279/how-are-c-array-members-handled-in-copy-control-functions – happydave Jan 03 '14 at 01:00

1 Answers1

2

The default copy constructor does member wise copy (thanks to Yuri whose comment below clarified this, as I had originally said bitwise copy). You can see this more clearly by changing your constructor and by providing an output operator for 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;
}

"What then is the case when instead of declaring int arr[10], a int *arr is used and the arr is dynamically allocated in the constructor, using the new keyword?"

In that case both objects will point to the same address, which means y could change the dynamically allocated array of x, and vice versa. Probably not what you want. So you would need to supply a copy constructor to avoid this:

#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;
}
Kurt Krueckeberg
  • 1,225
  • 10
  • 11