我想构建一个副本构造器Pair(const Pair& other)
。这以对另一个Pair
的只读引用为参数。它应该将新构造的Pair
设置为“深层副本”。但是我不知道如何在这些新位置设置整数,应该根据其他Pair
所指向的整数为其分配值。
class Pair {
public:
int *pa,*pb;
Pair(int a, int b);
Pair(const Pair & other);
~Pair();
};
Pair::Pair(int a, int b){
pa = new int;
pb = new int;
*pa = a;
*pb = b;
}
Pair::Pair(const Pair & other){
pa = new int;
pb = new int;
*pa = *(other.pa);
*pb = *(other.pb);
}
Pair::~Pair(){
delete pa;
delete pb;
}
int main() {
Pair p(15,16);
Pair q(p);
Pair *hp = new Pair(23,42);
delete hp;
std::cout << "If this message is printed,"
<< " at least the program hasn't crashed yet!\n"
<< "But you may want to print other diagnostic messages too." << std::endl;
return 0;
}
答案 0 :(得分:2)
您的转换构造函数没有为其分配的int
分配值,也没有将这些指针分配给类成员。
您的 copy 构造函数同样没有将分配的指针分配给类成员。访问*
的成员时,它也没有正确使用other
运算符。
您的析构函数需要delete
构造函数分配的类成员。
您需要添加副本分配运算符才能正确完成Rule of 3。
尝试一下:
class Pair {
public:
int *pa,*pb;
Pair(int a, int b);
Pair(const Pair & other);
~Pair();
Pair& operator=(const Pair & other);
};
Pair::Pair(int a, int b){
pa = new int;
pb = new int;
*pa = a;
*pb = b;
/* alternatively:
pa = new int(a);
pb = new int(b);
*/
}
Pair::Pair(const Pair & other){
pa = new int;
pb = new int;
*pa = *(other.pa);
*pb = *(other.pb);
/* alternatively:
pa = new int(*(other.pa));
pb = new int(*(other.pb));
*/
}
Pair::~Pair(){
delete pa;
delete pb;
}
Pair& Pair::operator=(const Pair & other){
*pa = *(other.pa);
*pb = *(other.pb);
return *this;
}
int main() {
Pair p(15,16);
Pair q(p);
Pair *hp = new Pair(23,42);
p = *hp;
delete hp;
std::cout << "If this message is printed,"
<< " at least the program hasn't crashed yet!\n"
<< "But you may want to print other diagnostic messages too." << std::endl;
return 0;
}
答案 1 :(得分:1)
您的第一个构造函数可能如下所示:
Pair::Pair(int a, int b)
: pa(new int(a))
, pb(new int(b))
{
}
您无需通过转发到第一个构造函数来多次编写复杂的代码。
Pair::Pair(const Pair & other)
: Pair(*other.pa, *other.pb)
{
}
另一件事是,您还必须实现赋值运算符。否则,如果您不小心进行分配,您的代码将很容易出错(因为假设析构函数已正确实现,您将有一个双delete
。
话虽如此,您的析构函数应该是:
Pair::~Pair()
{
delete pa;
delete pb;
}
正如其他人所说,直接为成员使用int
会更简单,因为您不必自己定义复制和分配。
// Inside class declaration
Pair &operator=(const Pair &other);
// With other definitions.
Pair &Pair::operator=(const Pair &other)
{
*pa = *other.pa;
*pb = *other.pb;
return *this;
}
如果您确实需要指针,那么我建议您改用std::unique_ptr
。
在您的课程中,声明变为std::unique_ptr<int> pa;
,对于pb
则类似。届时,您的析构函数将变为空。其余代码可以保持不变。
此外,最好避免使用变量成员
public
,在这种情况下,甚至在动态分配内存的情况下,更是如此。
答案 2 :(得分:0)
您可以使用自定义构造函数,如下复制构造函数:
[('Jack', 90, 190), ('Thomas', 70, 180),('Oliver', 75, 180),('Charlie', 80, 180), ('Jacob', 60, 175), ('Harry', 75, 175)]
答案 3 :(得分:-1)
您的init构造函数和copy构造函数可能会出现一些错误。
init构造函数应为:
Pair::Pair(int a, int b){
pa = new int;
pb = new int;
*pa = a;
*pb = b;
}
复制构造函数应为:
Pair::Pair(const Pair & other){
pa = new int;
pb = new int;
*pa = *(other.pa);
*pb = *(other.pb);
}