我知道这可能听起来微不足道,但我是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.arr
和other.arr
指向相同或不同的数组时?
如果执行了复制,它是执行浅拷贝还是深拷贝?
如果不是声明int arr[10]
,而是使用int *arr
并使用arr
关键字在构造函数中动态分配new
,那么会是什么情况呢? / p>
非常感谢!
编辑:我的发现
在声明int arr[10]
的情况下,是否复制了一个新数组,并且新数组中的元素指向原始数组中的对象?
当使用new
关键字来动态分配时,复制的数组仍然是指向复制对象数组的指针?
答案 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;
}