简体   繁体   English

为什么我的复制构造函数不起作用?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM