类不存在默认构造函数的错误 [英] Error where no default constructor exists for a class

查看:41
本文介绍了类不存在默认构造函数的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个程序,该程序应该解析命令行输入、读取输入文本文件,然后执行测试文件中指定的步骤序列.

I'm working on a program that is supposed to parse a command-line input, read an input text file, and then execute the sequence of steps specified from the test file.

在标记器类上工作一段时间后,我遇到了障碍,即错误,我不确定如何解决.

After working on the tokenizer class for some time, I've hit a wall, namely an error, that I'm not really sure how to solve.

所以,我有 Tokenizer.h:

So, I have 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:

And 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>':没有合适的默认>构造函数可用

'std::basic_ostream>': no appropriate default >constructor available

用于构造函数.后来,当我使用 'stream = t.stream' 和 '_os = t._os' 时,我得到了错误

for the constructor. Later, when I use 'stream = t.stream' and '_os = t._os' I get the error

function "std::basic_ostream<_Elem, _Traits>::operator=(const >std::basic_ostream<_Elem, _Traits>::_Myt &) [with _Elem=char, >_Traits=std::char_traits]"(在 >"x:\Visual\VC\include\ostream" 的第 85 行声明)不能被引用——它是一个已删除的 > 函数

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.

I've been trying to find some sort of solution for the first error, but I don't understand what's causing it. Creating a copy constructor was suggested to me, but it doesn't seem to have fixed the issue. I've also included Token.h below.

#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

如果我太含糊或类似的东西,我提前道歉.我很乐意提供任何其他需要的东西(因为我现在被困住了).

I apologize in advance if I'm being too vague or something along those lines. I'm more than happy to provide anything else needed (since I'm stuck at the moment).

推荐答案

编译器错误信息很清楚.当您使用:

The compiler error message is very clear. When you use:

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_.

the member variable os_ is default constructed. Since there is no default constructor in std::ostream, os_ cannot be initialized.

我猜你的意思是用Tokenizer的构造函数的输入参数初始化成员变量os_,比如:

I am guessing that you mean to initialize the member variable os_ with the input argument to the constructor of Tokenizer, like:

Tokenizer::Tokenizer(const std::string& s, std::ostream& o) : os_(o) 
{
   ...

即使这样也行不通,因为 std::ostream 没有复制构造函数.您需要将成员变量更改为引用对象.

Even that won't work since std::ostream does not have a copy constructor. You'll need to change the member variable to a reference object.

std::ostream& os_;

然后,您可以安全地使用:

Then, you can safely use:

Tokenizer::Tokenizer(const std::string& s, std::ostream& o) : os_(o) 
{
   ...

您只需要确保在销毁 Tokenizer 之前输入参数 o 没有被销毁.否则,Tokenizer 对象将留下一个悬空引用.

You just have to make sure that the input argument, o, is not destroyed before the Tokenizer is destroyed. Otherwise, the Tokenizer object will be left with a dangling reference.

这篇关于类不存在默认构造函数的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆