[英]Why doesn't my copy constructor work?
This is probably a no-brainer, but I'm a little stumped. 这可能是理所当然的,但我有些困惑。 I've had some trouble with my vectors not behaving nicely , and now it looks like I've found the culprit. 我的向量表现不佳时遇到了一些麻烦,现在看来我找到了罪魁祸首。 Here's a watered down version of my Player
class. 这是我的Player
类的精简版本。
class Player {
private:
std::string _firstName;
std::string _lastName;
public:
Player(std::string firstName, std::string lastName) {
_firstName = firstName;
_lastName = lastName;
};
Player(const Player& otherPlayer) {
_firstName = otherPlayer._firstName.c_str();
_lastName = otherPlayer._lastName.c_str();
std::cout << "Created " << _firstName << " " << _lastName << std::endl; // Why doesn't _firstName and _lastName contain anything?
};
std::string GetName() { return _firstName + " " + _lastName; };
};
int main(int argc, const char * argv[])
{
Player player1 = Player("Bill", "Clinton");
Player player2 = Player(player1);
std::cout << "Player: " << player2.GetName() << std::endl;
return 0;
}
The output is a meager Player:
. 输出是一个微薄的Player:
。 I'm not sure why my copy constructor doesn't do what I want it to do, in particular in light of advice such as this (Zac Howland's comment accounts for the c_str();
-part). 我不知道为什么我的拷贝构造函数不会做我想做的事情,特别是在咨询的光,如本 (扎克霍兰德的评论占c_str();
双组分)。 Am I violating the rule of three (which, btw, I still haven't totally gotten my head around)? 我是否违反了三个规则 (顺便说一句,我仍然还没有完全意识到这一点)? I'd be really grateful if anyone could point me in the right direction! 如果有人能指出正确的方向,我将不胜感激!
It works for me : http://ideone.com/aenViu 它对我有用 : http : //ideone.com/aenViu
I just addded : 我只是补充说:
#include <iostream>
#include <string>
But there is something I don't understand : 但是有些我不明白:
_firstName = otherPlayer._firstName.c_str();
_lastName = otherPlayer._lastName.c_str();
Why the .c_str()
? 为什么要使用.c_str()
? You convert the string
to char*
to assign it to a new string
? 您将string
转换为char*
以将其分配给新string
?
EDIT : From the comment, Zac Howland pointed : "Prior to C++11, if you wanted to ensure your string was copied (instead of reference counted), you had to use the c_str()
method to force it to copy the string. The new standard eliminates that, but if he's using an older compiler, or one that hasn't fully implemented C++11 yet, it will ensure a deep copy." 编辑:从评论中,Zac Howland指出: “在C ++ 11之前,如果要确保复制字符串(而不是引用计数),则必须使用c_str()
方法来强制它复制字符串。新标准消除了这种情况,但是如果他使用的是较旧的编译器,或者尚未完全实现C ++ 11的编译器,它将确保进行深度复制。”
Just do : 做就是了 :
_firstName = otherPlayer._firstName;
_lastName = otherPlayer._lastName;
And, do you really need this copy constructor ? 并且,您真的需要此副本构造函数吗? The default would do what you want I think... 默认值可以满足您的要求。
Also, instead of assigning the members : 另外,不要分配成员:
Player(std::string firstName, std::string lastName) {
_firstName = firstName;
_lastName = lastName;
}
use the member-initialization-list instead : 使用member-initialization-list代替:
Player(std::string firstName, std::string lastName) :
_firstName( std::move(firstName) ),
_lastName( std::move(lastName) )
{}
In the first case the string's default constructor is called and then string's copy-assignment operator, there could definitely be (minor) efficiency losses compared to the second case, which directly calls the copy-constructor. 在第一种情况下,先调用字符串的默认构造函数,然后再调用字符串的拷贝分配运算符,与第二种情况(直接调用拷贝构造函数)相比,肯定会存在(较小)效率损失。
Last thing, when it is possible, does not pass values as method arguments, pass references and even const references when they don't need to be modified : 最后一件事,如果可能的话,不需要将值作为方法参数传递,不需要引用甚至是const引用时,都无需修改它们:
Player( const std::string& firstName, const std::string& lastName )
// ^^^^^ ^ ^^^^^ ^
: _firstName( firstName ) // no move here, since args are constant references
, _lastName( lastName )
{}
Working live example of all the modifications. 所有修改的工作示例 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.