我在封装令牌向量的 TokenList 类上使用我的 Push 函数时遇到问题。每当我调用 Push 函数时,即使我正确初始化了 Token 变量,Token 类中的成员变量 word 也是空的。我也尝试使用整数,它存储垃圾数。
令牌类
class Token {
private:
class Impl;
std::unique_ptr<Impl> impl;
public:
Token();
Token(const Token& token);
Token(const std::string& word);
~Token();
std::string GetWord();
void SetWord(const std::string& word);
};
令牌列表类
class TokenList {
private:
class Impl;
std::unique_ptr<Impl> impl;
public:
TokenList();
TokenList(const TokenList& tokenList);
~TokenList();
std::size_t Size() const;
void Push(const Token& token);
Token& operator[](int i);
const Token& operator[](int i) const;
};
实现
class TokenList::Impl {
private:
std::vector<Token> tokens;
public:
/* .... */
void push(const Token& token) {
tokens.push_back(token);
}
};
void TokenList::Push(const Token& token) { impl->push(token); }
主要
TokenList tokens;
Token s1 ("hello");
Token s2 ("world");
tokens.Push(s1);
tokens.Push(s2);
for (int i = 0; i < tokens.Size(); ++i)
cout << i << ": " << tokens[i].GetWord() << endl;
这是我运行 main 时的输出:
0:
1:
我尝试使用字符串而不是 TokenList 作为矢量的类型参数,它运行良好。当我跟踪问题时,它是在推送函数中没有获得正确传递的令牌值。那么是什么原因导致 TokenList 的推送函数不采用 Token 类的成员值呢?
实现了所有丢失的代码,但我无法重现您的问题。请注意,我添加了一个复制赋值运算符,因为对于存储在不可移动的向量中的类型,这是必需的。我已经发布了下面的代码,以便您可以与您的实现进行比较。(这使用了一些C++11功能)
#include <string>
#include <vector>
#include <iostream>
#include <memory>
class Token {
private:
struct Impl;
std::unique_ptr<Impl> impl;
public:
Token();
Token(const Token& token);
Token(const std::string& word);
Token& operator=(const Token& token);
std::string GetWord();
void SetWord(const std::string& word);
};
class TokenList {
private:
struct Impl;
std::unique_ptr<Impl> impl;
public:
TokenList();
TokenList(const TokenList& tokenList);
std::size_t Size() const;
void Push(const Token& token);
Token& operator[](int i);
const Token& operator[](int i) const;
};
// Token Implementation
struct Token::Impl
{
std::string Word;
};
Token::Token() : impl{ std::make_unique<Impl>() }
{
}
Token::Token(const Token& token) : Token{}
{
impl->Word = token.impl->Word;
}
Token::Token(const std::string& word) : Token{}
{
impl->Word = word;
}
Token& Token::operator=(const Token& token)
{
impl->Word = token.impl->Word;
return *this;
}
std::string Token::GetWord()
{
return impl->Word;
}
void Token::SetWord(const std::string& word)
{
impl->Word = word;
}
// TokenList Implementation
struct TokenList::Impl
{
std::vector<Token> tokens;
void push(const Token& token)
{
tokens.push_back(token);
}
};
TokenList::TokenList() : impl{ std::make_unique<Impl>() }
{
}
TokenList::TokenList(const TokenList& tokenList) : TokenList{}
{
impl->tokens = tokenList.impl->tokens;
}
void TokenList::Push(const Token& token)
{
impl->push(token);
}
std::size_t TokenList::Size() const
{
return impl->tokens.size();
}
Token& TokenList::operator[](int i)
{
return impl->tokens[i];
}
const Token& TokenList::operator[](int i) const
{
return impl->tokens[i];
}
int main()
{
TokenList tokens;
Token s1("hello");
Token s2("world");
tokens.Push(s1);
tokens.Push(s2);
for (int i = 0; i < tokens.Size(); ++i)
std::cout << i << ": " << tokens[i].GetWord() << std::endl;
}