[英]Why weird characters shown in cout for string variable in C++?
我有以下代码:
Card.h
:
#include <string>
using namespace std;
class Card
{
public:
Card(string name);
~Card() {};
string GetName();
private:
string Name;
};
Card.cpp
:
#include "Card.h"
using namespace std;
Card::Card(string name) {Name=name;};
string Card::GetName() {return Name;}
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
:
#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
:
#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
:
#include "Player.h"
using namespace std;
Player::Player(Deck _deck)
{
this->deck = _deck;
}
void Player::Beginning()
{
Card& c = deck.DrawCard();
}
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;
}
我得到的输出是:
THIS THIS GREAT PLAYER was drawn
�\IS GREAT PLAYER popped from deck
为什么第二行用奇怪的字符代替“ THIS THIS”?
您在此函数中有未定义的行为:
Card& Deck::DrawCard() {
// ...
Card &c = cardsindeck.back();
// ...
cardsindeck.pop_back();
cout << c.GetName()<<" popped from deck "<<endl;
return c;
}
首先,为cardsindeck
的最后一个元素cardsindeck
别名c
。 很好,对其成员函数的访问也很好。 然后,使用cardsindeck.pop_back();
从容器中删除该元素cardsindeck.pop_back();
。 从std::vector::pop_back
的文档中,我们看到了
除
back()
和end()
外,没有迭代器或引用无效。
这就是这里的问题。 您正在引用back()
,并且该引用无效。 它必须是-您正在从容器中删除c
引用的向量中的元素。 那么,例如通过GetName()
访问其成员就是UB。
您可以通过复制 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;
请注意,这需要将成员函数的签名更改为
Card Deck::DrawCard()
返回值不再是参考。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.