简体   繁体   English

在C ++中,为什么在cout中显示的字符串变量中的字符奇怪?

[英]Why weird characters shown in cout for string variable in C++?

I have the following code: 我有以下代码:

Card.h : Card.h

#include <string>

using namespace std;

class Card
{
public:
    Card(string name);
    ~Card() {}; 

    string GetName();

private:
    string Name;

};

Card.cpp : Card.cpp

#include "Card.h"

using namespace std;

Card::Card(string name) {Name=name;};
string Card::GetName() {return Name;}

Deck.h : Deck.h

#include "Card.h"
#include <vector>

class Deck {
    public:
        Card& DrawCard();
        void AddCardToDeck(Card& c);

        Deck();
        ~Deck();

    private:
        std::vector <Card> cardsindeck;
};

Deck.cpp : Deck.cpp

#include "Deck.h"
#include <vector>
#include <iostream>

using namespace std;

Card& Deck::DrawCard() {
    //cout << cardsindeck.back().GetName()<<" was drawn "<<endl;
    Card &c = cardsindeck.back();
    cout << c.GetName()<<" was drawn "<<endl;
    cardsindeck.pop_back();
    cout << c.GetName()<<" popped from deck "<<endl;
    return c;
}

Deck::Deck()
{

}

Deck::~Deck()
{
}

void Deck::AddCardToDeck(Card& c) {
    cardsindeck.push_back(c);
}

Player.h : Player.h

#include "Deck.h"
#include <vector>

using namespace std;

class Player {
    public:
        void Beginning();
        Player(Deck _deck);
        ~Player() {};

    private:
        vector <Card> cardsindeck;
        Deck deck;

};

Player.cpp : Player.cpp

#include "Player.h"

using namespace std;

Player::Player(Deck _deck)
{
    this->deck = _deck;
}

void Player::Beginning()
{
    Card& c = deck.DrawCard();

}

main.cpp : main.cpp

#include "Player.h"
#include <iostream>
#include <string>

using namespace std;

int main()
{

    Deck aDeck;
    vector <Card> aHand;

    Card c=Card("THIS THIS GREAT PLAYER");
    Card& c1 =c;
    aDeck.AddCardToDeck(c1);

    Player P = Player(aDeck);
    P.Beginning();

    return 0;
} 

The output I get is: 我得到的输出是:

THIS THIS GREAT PLAYER was drawn 
�\IS GREAT PLAYER popped from deck 

Why does the 2nd line have that weird chars in place of "THIS THIS" ? 为什么第二行用奇怪的字符代替“ THIS THIS”?

You have undefined behavior in this function: 您在此函数中有未定义的行为:

Card& Deck::DrawCard() {
    // ...
    Card &c = cardsindeck.back();
    // ...
    cardsindeck.pop_back();
    cout << c.GetName()<<" popped from deck "<<endl;

    return c;
}

First, you alias the last element of cardsindeck with a reference called c . 首先,为cardsindeck的最后一个元素cardsindeck别名c This is fine, and access to its member function is fine, too. 很好,对其成员函数的访问也很好。 Then, you remove the element from the container with cardsindeck.pop_back(); 然后,使用cardsindeck.pop_back();从容器中删除该元素cardsindeck.pop_back(); . From the docs on std::vector::pop_back , we see that std::vector::pop_back的文档中,我们看到了

No iterators or references except for back() and end() are invalidated. back()end()外,没有迭代器或引用无效。

And that's the issue here. 这就是这里的问题。 You are having a reference to back() , and that is invalidated. 您正在引用back() ,并且该引用无效。 It must be - you are deleting the element in the vector that c refers to from the container. 它必须是-您正在从容器中删除c引用的向量中的元素。 Accessing its members then eg by GetName() is UB, then. 那么,例如通过GetName()访问其成员就是UB。

You can easily fix the issue by copying the return value of cardsindeck.back() like this: 您可以通过复制 cardsindeck.back()的返回值来轻松解决问题,如下所示:

Card c = cardsindeck.back();
//  ^^ No reference. The last element is copied

cardsindeck.pop_back(); // Doens't affect the copied instance above

return c;

Note that this requires changing the signature of the member function to 请注意,这需要将成员函数的签名更改为

Card Deck::DrawCard()

where the return value is no reference anymore. 返回值不再是参考。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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