复制构造函数
Copy Constructor
class Gun{
private:
int bullet;
public:
Gun(int bnum) : bullet(bnum) { }
};
class Police{
private:
Gun * pistol;
public:
Police(int bNum) : {
if(bNum>0)
pistol = new Gun(bNum);
else
pistol=NULL;
}
Police(const Police& ref){
pistol=new Gun(*(ref.pistol)); //Confused about this part.
}
};
我目前正在学习 C++,我对 Police 的复制构造函数中发生的事情有点迷茫。我相信 Gun 的构造函数只接受整数,但如何将 *(ref.pistol) 作为参数分配给它?我认为 *(ref.pistol) 是一个 Gun 对象,而不是一个整数。
如果您自己没有显式声明一个复制构造函数,编译器总是隐式声明一个复制构造函数(尽管在某些情况下它可以被删除)。您感到困惑的那一行调用了这个隐式声明的复制构造函数。
这个隐式声明的复制构造函数是 public 并且(如果使用它)它只是进行成员复制,即,就好像你已经写了
public:
Gun(const Gun& other): bullet(other.bullet) {}
I believe Gun's constructor only takes integers, but how do you assign *(ref.pistol) to it as a parameter? I think *(ref.pistol) is a Gun object, not an integer.
你说得对,*(ref.pistol) 是 Gun,不是整数。
在 C++ 中,您可以在不声明的情况下使用某些特殊方法,编译器会为您生成一些(希望如此)合适的方法。拷贝构造函数就是其中之一。
在 Police 的复制构造函数中,使用默认的 Gun 复制构造函数创建了一个新的 Gun
,然后将其分配给 this->pistol
。
如果你想明确地说你想要默认的复制构造函数,你可以在 Gun 中这样写:
Gun(const Gun& other) = default;
同样适用于构造函数、析构函数、copy/move 构造函数和赋值运算符。
*(ref.pistol)
正在访问 Gun
实例,因此代码试图调用 Gun
的 复制构造函数 ,但是您有没有明确定义。您只定义了一个非默认的非复制构造函数,因此编译器可能 忽略创建默认的复制构造函数。不过,您可以显式定义自己的复制构造函数:
class Gun{
private:
int bullet;
public:
Gun(int bnum) : bullet(bnum) { }
Gun(const Gun& ref) : bullet(ref.bullet) { }
};
或者,在 C++11 及更高版本中:
class Gun{
private:
int bullet;
public:
Gun(int bnum) : bullet(bnum) { }
Gun(const Gun& ref) = default;
};
无论哪种方式,你都可以像这样使用它(不要忘记 pistol
可以是 NULL,所以你必须在你的 Police
复制构造函数中检查它):
class Police{
private:
Gun * pistol;
public:
Police(int bNum) {
if(bNum>0)
pistol = new Gun(bNum);
else
pistol=NULL;
}
Police(const Police& ref) {
if (ref.pistol)
pistol=new Gun(*(ref.pistol));
else
pistol=NULL;
}
~Police() {
delete pistol;
}
};
并且不要忘记对 复制赋值运算符 也应用类似的逻辑(在处理手动深度复制实现时,不要忘记 rule of 3 ,以及 C++11 及更高版本中 5 的 规则:
class Gun{
private:
...
public:
...
// the implicit operator is sufficient in this particular example,
// this is being shown just for demonstation purposes...
Gun& operator=(const Gun& ref) {
bullet = ref.bullet;
return *this;
}
// or, in C++11 and later
//Gun& operator=(const Gun& ref) = default;
};
class Police{
private:
...
public:
...
Police& operator=(const Police& ref) {
if (ref != *this) {
delete pistol;
pistol = NULL;
if (ref.pistol)
pistol=new Gun(*(ref.pistol));
}
return *this;
}
// alternatively:
/*
Police& operator=(const Police& ref) {
if (ref != *this) {
if (pistol) {
if (ref.pistol) {
*pistol = *(ref.pistol);
return *this;
}
delete pistol;
pistol = NULL;
}
if (ref.pistol)
pistol=new Gun(*(ref.pistol));
}
return *this;
}
*/
};
class Gun{
private:
int bullet;
public:
Gun(int bnum) : bullet(bnum) { }
};
class Police{
private:
Gun * pistol;
public:
Police(int bNum) : {
if(bNum>0)
pistol = new Gun(bNum);
else
pistol=NULL;
}
Police(const Police& ref){
pistol=new Gun(*(ref.pistol)); //Confused about this part.
}
};
我目前正在学习 C++,我对 Police 的复制构造函数中发生的事情有点迷茫。我相信 Gun 的构造函数只接受整数,但如何将 *(ref.pistol) 作为参数分配给它?我认为 *(ref.pistol) 是一个 Gun 对象,而不是一个整数。
如果您自己没有显式声明一个复制构造函数,编译器总是隐式声明一个复制构造函数(尽管在某些情况下它可以被删除)。您感到困惑的那一行调用了这个隐式声明的复制构造函数。
这个隐式声明的复制构造函数是 public 并且(如果使用它)它只是进行成员复制,即,就好像你已经写了
public:
Gun(const Gun& other): bullet(other.bullet) {}
I believe Gun's constructor only takes integers, but how do you assign *(ref.pistol) to it as a parameter? I think *(ref.pistol) is a Gun object, not an integer.
你说得对,*(ref.pistol) 是 Gun,不是整数。 在 C++ 中,您可以在不声明的情况下使用某些特殊方法,编译器会为您生成一些(希望如此)合适的方法。拷贝构造函数就是其中之一。
在 Police 的复制构造函数中,使用默认的 Gun 复制构造函数创建了一个新的 Gun
,然后将其分配给 this->pistol
。
如果你想明确地说你想要默认的复制构造函数,你可以在 Gun 中这样写:
Gun(const Gun& other) = default;
同样适用于构造函数、析构函数、copy/move 构造函数和赋值运算符。
*(ref.pistol)
正在访问 Gun
实例,因此代码试图调用 Gun
的 复制构造函数 ,但是您有没有明确定义。您只定义了一个非默认的非复制构造函数,因此编译器可能 忽略创建默认的复制构造函数。不过,您可以显式定义自己的复制构造函数:
class Gun{
private:
int bullet;
public:
Gun(int bnum) : bullet(bnum) { }
Gun(const Gun& ref) : bullet(ref.bullet) { }
};
或者,在 C++11 及更高版本中:
class Gun{
private:
int bullet;
public:
Gun(int bnum) : bullet(bnum) { }
Gun(const Gun& ref) = default;
};
无论哪种方式,你都可以像这样使用它(不要忘记 pistol
可以是 NULL,所以你必须在你的 Police
复制构造函数中检查它):
class Police{
private:
Gun * pistol;
public:
Police(int bNum) {
if(bNum>0)
pistol = new Gun(bNum);
else
pistol=NULL;
}
Police(const Police& ref) {
if (ref.pistol)
pistol=new Gun(*(ref.pistol));
else
pistol=NULL;
}
~Police() {
delete pistol;
}
};
并且不要忘记对 复制赋值运算符 也应用类似的逻辑(在处理手动深度复制实现时,不要忘记 rule of 3 ,以及 C++11 及更高版本中 5 的 规则:
class Gun{
private:
...
public:
...
// the implicit operator is sufficient in this particular example,
// this is being shown just for demonstation purposes...
Gun& operator=(const Gun& ref) {
bullet = ref.bullet;
return *this;
}
// or, in C++11 and later
//Gun& operator=(const Gun& ref) = default;
};
class Police{
private:
...
public:
...
Police& operator=(const Police& ref) {
if (ref != *this) {
delete pistol;
pistol = NULL;
if (ref.pistol)
pistol=new Gun(*(ref.pistol));
}
return *this;
}
// alternatively:
/*
Police& operator=(const Police& ref) {
if (ref != *this) {
if (pistol) {
if (ref.pistol) {
*pistol = *(ref.pistol);
return *this;
}
delete pistol;
pistol = NULL;
}
if (ref.pistol)
pistol=new Gun(*(ref.pistol));
}
return *this;
}
*/
};