class 不存在默认构造函数的错误
Error where no default constructor exists for a class
我正在开发一个程序,该程序应该解析命令行输入、读取输入文本文件,然后执行测试文件中指定的步骤序列。
在分词器 class 上工作了一段时间后,我遇到了瓶颈,即一个错误,我不太确定如何解决。
所以,我有 Tokenizer.h:
#ifndef _TOKENIZER_GUARD
#define _TOKENIZER_GUARD 1
#include <string>
#include <cstdlib>
#include <climits>
#include <cfloat>
#include <iostream>
#include <fstream>
#include "Token.h"
//
// A class to create a sequence of tokens from an input file stream.
//
class Tokenizer
{
public:
Tokenizer(const std::string&, std::ostream&);
Tokenizer(Tokenizer&); // Copy Constructor -I
virtual ~Tokenizer();
virtual int nextInt();
virtual bool hasNextInt() const;
virtual long nextLongInt();
virtual bool hasNextLongInt() const;
virtual float nextFloat();
virtual bool hasNextFloat() const;
virtual std::string next();
virtual bool hasNext() const;
Tokenizer& operator= (Tokenizer&); // overloaded equals operator
protected:
private:
Tokenizer();
std::ifstream stream;
std::ostream _os;
Token _token;
};
#endif
和Tokenizer.cpp:
#include <string>
#include <cstdlib>
#include <climits>
#include <cfloat>
#include <iostream>
#include <fstream>
#include "Tokenizer.h"
Tokenizer::Tokenizer()
{ //error occurs here
}
// Constructor
Tokenizer::Tokenizer(const std::string& s, std::ostream& o)
{ //error occurs here
stream.open(s);
std::string t;
getline(stream, t, ' ');
_token = Token(t);
}
// Copy Constructor
Tokenizer::Tokenizer(Tokenizer& t) :_token(t._token), stream(t.stream), _os(t._os)
{
}
// Destructor
Tokenizer::~Tokenizer()
{
stream.close();
}
// Saves current int to return, then moves _token to the next value
int Tokenizer::nextInt()
{
int temp = _token.toInteger();
std::string t;
getline(stream, t, ' ');
_token = Token(t);
return temp;
}
// Checks to see if there is a next value and if it is an int
bool Tokenizer::hasNextInt() const
{
return _token.isInteger() && hasNext();
}
// same as nextInt but long -I
long Tokenizer::nextLongInt()
{
long temp = _token.toLongInteger();
std::string t;
getline(stream, t, ' ');
_token = Token(t);
return temp;
}
// same as hasNextInt but Long
bool Tokenizer::hasNextLongInt() const
{
return _token.isLongInteger() && hasNext();
}
// same as nextInt but Float
float Tokenizer::nextFloat()
{
float temp = _token.toFloat();
std::string t;
getline(stream, t, ' ');
_token = Token(t);
return temp;
}
// same as hasNextInt but float
bool Tokenizer::hasNextFloat() const
{
return _token.isFloat() && hasNext();
}
//Returns the next token
std::string Tokenizer::next()
{
std::string temp = _token.get();
std::string t;
getline(stream, t, ' ');
_token = Token(t);
return temp;
}
//True when it is not the end of the file
bool Tokenizer::hasNext() const
{
return stream.eofbit != 1;
}
//Overloaded = operator
Tokenizer& Tokenizer::operator= (Tokenizer& t)
{
_token = t._token;
stream = t.stream;
_os = t._os; //error occurs here
}
我收到错误
'std::basic_ostream>': no appropriate default >constructor available
对于构造函数。后来,当我使用 'stream = t.stream' 和 '_os = t._os' 时,我得到了错误
function "std::basic_ostream<_Elem, _Traits>::operator=(const >std::basic_ostream<_Elem, _Traits>::_Myt &) [with _Elem=char, >_Traits=std::char_traits]" (declared at line 85 of >"x:\Visual\VC\include\ostream") cannot be referenced -- it is a deleted >function
我一直在尝试为第一个错误找到某种解决方案,但我不明白是什么原因造成的。有人向我建议创建一个复制构造函数,但它似乎并没有解决这个问题。我还在下面包含了 Token.h。
#ifndef _TOKEN_GUARD
#define _TOKEN_GUARD 1
#include <string>
#include <cstdlib>
#include <climits>
#include <cfloat>
//
// Token class
//
class Token
{
public:
Token(const std::string& t) : _token(t) { }
virtual std::string get() const { return _token; }
virtual long toLongInteger() const;
virtual bool isLongInteger() const;
virtual int toInteger() const; // for int and is int functions
virtual bool isInteger() const; //
virtual float toFloat() const;
virtual bool isFloat() const;
virtual bool isNonNumeric() const;
Token() : _token("") {}
std::string _token;
protected:
};
#endif
如果我过于含糊或类似的话,我提前道歉。我非常乐意提供任何其他需要的东西(因为我现在卡住了)。
编译错误信息很清楚。当您使用:
Tokenizer::Tokenizer(const std::string& s, std::ostream& o)
{ //error occurs here
stream.open(s);
std::string t;
getline(stream, t, ' ');
_token = Token(t);
}
成员变量os_
默认构造。由于std::ostream
中没有默认构造函数,os_
无法初始化。
我猜你的意思是用Tokenizer
的构造函数的输入参数来初始化成员变量os_
,比如:
Tokenizer::Tokenizer(const std::string& s, std::ostream& o) : os_(o)
{
...
即使这样也行不通,因为 std::ostream
没有复制构造函数。您需要将成员变量更改为引用对象。
std::ostream& os_;
那么,你就可以安心使用了:
Tokenizer::Tokenizer(const std::string& s, std::ostream& o) : os_(o)
{
...
您只需确保输入参数 o
在 Tokenizer
被销毁之前没有被销毁。否则,Tokenizer
对象将留下悬空引用。
我正在开发一个程序,该程序应该解析命令行输入、读取输入文本文件,然后执行测试文件中指定的步骤序列。
在分词器 class 上工作了一段时间后,我遇到了瓶颈,即一个错误,我不太确定如何解决。
所以,我有 Tokenizer.h:
#ifndef _TOKENIZER_GUARD
#define _TOKENIZER_GUARD 1
#include <string>
#include <cstdlib>
#include <climits>
#include <cfloat>
#include <iostream>
#include <fstream>
#include "Token.h"
//
// A class to create a sequence of tokens from an input file stream.
//
class Tokenizer
{
public:
Tokenizer(const std::string&, std::ostream&);
Tokenizer(Tokenizer&); // Copy Constructor -I
virtual ~Tokenizer();
virtual int nextInt();
virtual bool hasNextInt() const;
virtual long nextLongInt();
virtual bool hasNextLongInt() const;
virtual float nextFloat();
virtual bool hasNextFloat() const;
virtual std::string next();
virtual bool hasNext() const;
Tokenizer& operator= (Tokenizer&); // overloaded equals operator
protected:
private:
Tokenizer();
std::ifstream stream;
std::ostream _os;
Token _token;
};
#endif
和Tokenizer.cpp:
#include <string>
#include <cstdlib>
#include <climits>
#include <cfloat>
#include <iostream>
#include <fstream>
#include "Tokenizer.h"
Tokenizer::Tokenizer()
{ //error occurs here
}
// Constructor
Tokenizer::Tokenizer(const std::string& s, std::ostream& o)
{ //error occurs here
stream.open(s);
std::string t;
getline(stream, t, ' ');
_token = Token(t);
}
// Copy Constructor
Tokenizer::Tokenizer(Tokenizer& t) :_token(t._token), stream(t.stream), _os(t._os)
{
}
// Destructor
Tokenizer::~Tokenizer()
{
stream.close();
}
// Saves current int to return, then moves _token to the next value
int Tokenizer::nextInt()
{
int temp = _token.toInteger();
std::string t;
getline(stream, t, ' ');
_token = Token(t);
return temp;
}
// Checks to see if there is a next value and if it is an int
bool Tokenizer::hasNextInt() const
{
return _token.isInteger() && hasNext();
}
// same as nextInt but long -I
long Tokenizer::nextLongInt()
{
long temp = _token.toLongInteger();
std::string t;
getline(stream, t, ' ');
_token = Token(t);
return temp;
}
// same as hasNextInt but Long
bool Tokenizer::hasNextLongInt() const
{
return _token.isLongInteger() && hasNext();
}
// same as nextInt but Float
float Tokenizer::nextFloat()
{
float temp = _token.toFloat();
std::string t;
getline(stream, t, ' ');
_token = Token(t);
return temp;
}
// same as hasNextInt but float
bool Tokenizer::hasNextFloat() const
{
return _token.isFloat() && hasNext();
}
//Returns the next token
std::string Tokenizer::next()
{
std::string temp = _token.get();
std::string t;
getline(stream, t, ' ');
_token = Token(t);
return temp;
}
//True when it is not the end of the file
bool Tokenizer::hasNext() const
{
return stream.eofbit != 1;
}
//Overloaded = operator
Tokenizer& Tokenizer::operator= (Tokenizer& t)
{
_token = t._token;
stream = t.stream;
_os = t._os; //error occurs here
}
我收到错误
'std::basic_ostream>': no appropriate default >constructor available
对于构造函数。后来,当我使用 'stream = t.stream' 和 '_os = t._os' 时,我得到了错误
function "std::basic_ostream<_Elem, _Traits>::operator=(const >std::basic_ostream<_Elem, _Traits>::_Myt &) [with _Elem=char, >_Traits=std::char_traits]" (declared at line 85 of >"x:\Visual\VC\include\ostream") cannot be referenced -- it is a deleted >function
我一直在尝试为第一个错误找到某种解决方案,但我不明白是什么原因造成的。有人向我建议创建一个复制构造函数,但它似乎并没有解决这个问题。我还在下面包含了 Token.h。
#ifndef _TOKEN_GUARD
#define _TOKEN_GUARD 1
#include <string>
#include <cstdlib>
#include <climits>
#include <cfloat>
//
// Token class
//
class Token
{
public:
Token(const std::string& t) : _token(t) { }
virtual std::string get() const { return _token; }
virtual long toLongInteger() const;
virtual bool isLongInteger() const;
virtual int toInteger() const; // for int and is int functions
virtual bool isInteger() const; //
virtual float toFloat() const;
virtual bool isFloat() const;
virtual bool isNonNumeric() const;
Token() : _token("") {}
std::string _token;
protected:
};
#endif
如果我过于含糊或类似的话,我提前道歉。我非常乐意提供任何其他需要的东西(因为我现在卡住了)。
编译错误信息很清楚。当您使用:
Tokenizer::Tokenizer(const std::string& s, std::ostream& o)
{ //error occurs here
stream.open(s);
std::string t;
getline(stream, t, ' ');
_token = Token(t);
}
成员变量os_
默认构造。由于std::ostream
中没有默认构造函数,os_
无法初始化。
我猜你的意思是用Tokenizer
的构造函数的输入参数来初始化成员变量os_
,比如:
Tokenizer::Tokenizer(const std::string& s, std::ostream& o) : os_(o)
{
...
即使这样也行不通,因为 std::ostream
没有复制构造函数。您需要将成员变量更改为引用对象。
std::ostream& os_;
那么,你就可以安心使用了:
Tokenizer::Tokenizer(const std::string& s, std::ostream& o) : os_(o)
{
...
您只需确保输入参数 o
在 Tokenizer
被销毁之前没有被销毁。否则,Tokenizer
对象将留下悬空引用。