Question

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?

Was it helpful?

Solution

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;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top