没有默认构造函数可用于指定的类,结构或联合[重复]

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了没有默认构造函数可用于指定的类,结构或联合[重复]相关的知识,希望对你有一定的参考价值。

这个问题在这里已有答案:

试图创建一个类。当我在构造函数之后放置{时,vs2015向我显示错误

没有默认构造函数可用于指定的类,结构或联合。

Theres代码片段:

NumberExpression.h:

class NumberExpression : Expression {
private:
    Token m_token;
public:
    NumberExpression(Token tok);
    double evaluate();
};

NumberExpression.cpp:

NumberExpression::NumberExpression(Token tok) {
    m_token = tok;
}

Token.h:

class Token {
public:
    enum TYPE { NUM, ADD, SUB, MUL, DIV, EoF };
private:
    char* m_text;
    TYPE m_type;
public:
    Token(TYPE type, char* text);

    TYPE getType() const { return m_type; }
    char* getText() const { return m_text; }
};

我知道我可以创建一个Empty构造函数,但为什么会出现这个错误?

答案

OP问这个:

我知道我可以创建一个Empty构造函数,但为什么会出现这个错误?

你的类NumberExpression有一个构造函数,它接受一个Token对象。

在这个类的构造函数体中,您使用的是Token's复制赋值运算符。 m_token = tok;默认由编译器定义。

在你的类Token中,你声明和定义的构造函数在其参数列表中需要2个参数。然而,当您尝试使用复制赋值运算符时,这就是编译器为您提供该错误的原因。您正在尝试分配Token对象的副本并将其保存(存储)到NumberExpression的成员。由于你为constructor声明了一个带有两个参数的Token,编译器不会使用默认的ctorcopy ctor,因为你在声明一个user defined constructor之后没有提供一个,它找不到默认的ctor的声明或定义。


有三种方法可以解决这个问题:

  1. 在标题中提供Default或空构造函数,简单如下: Token() = default; Token(); Token() {}
  2. 使用NumberExpression's类成员初始化列表,如其他人所述: NumberExpression::NumberExpression( Token token ) : m_token( token ) {...}
  3. 或者两者结合使用。

此外,如果要将单个对象传递给NumberExpression's构造函数,如果要防止编译器自动隐式转换或强制转换,并且想要使其严格,则可以在构造函数的声明中使用explicit关键字:

class NumberExpression : public Expression {
private: 
    Token m_token;
public:
    explicit NumberExpression( Token token ) : m_token( token ) {}
    double evaluate();
};

要设置令牌类的默认初始化列表:

class Token {
public:
    enum Type {
        INVALID = -1,
        NUM,
        ADD,
        SUB,
        MUL,
        DIV,
        EOF
    };
private:
    char* m_text;
    Type m_type;
public:
    Token(Type type, char* text) : m_type(INVALID), m_text(nullptr) {}

    Type getType() const { return m_type; }
    char* getText() const { return m_text; }
};
另一答案
NumberExpression::NumberExpression(Token tok) {
    m_token = tok;
}

相当于

NumberExpression::NumberExpression(Token tok) : m_token() {
    m_token = tok;
}

由于Token没有默认构造函数,编译器会抱怨。这是正确的。

改变它以使用Token的有效构造函数。

NumberExpression::NumberExpression(Token tok) : m_token(tok) {}
另一答案

你应该直接通过m_token初始化member intializer list

对于无法进行缺省初始化的成员(例如引用成员和const限定类型),必须指定成员初始值设定项。

EG

NumberExpression::NumberExpression(Token tok) : m_token(tok) {
}

在您的实现中,m_token将首先默认初始化,然后在NumberExpression的构造函数体中分配。但Token没有默认构造函数。

以上是关于没有默认构造函数可用于指定的类,结构或联合[重复]的主要内容,如果未能解决你的问题,请参考以下文章

默认构造函数,为啥我的类似乎有三个?当编译器将类视为结构时?

当有多个实现接口的类时,如何指定构造函数注入[重复]

使用杰克逊的 JSON 反序列化:没有找到适合类型的构造函数 - 可以提供默认构造函数或注释构造函数 [重复]

构造函数与默认构造函数

C ++中的结构构造函数?

c# 中的类和构造函数在不同程序集中的 c# 中的默认访问说明符是啥 [重复]