2017-12-20 6 views
0

クラスの作成を試みています。私は、コンストラクタの後{を入れると、vs2015は私にエラー指定されたクラス、構造体、または共用体にデフォルトのコンストラクタはありません

を示しんデフォルトコンストラクタは、指定されたクラス、構造体、または共用体のために利用可能ではありません。

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:

は、コードスニペットをTheresの

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; } 
}; 

私は空のコンストラクタを作成できますが、なぜこのエラーが発生するのでしょうか?

答えて

2

ザ・OPはこれを尋ねた:

を私はちょうど空のコンストラクタを作成することができることを知っているが、このエラーはなぜ起こりますか?

クラスNumberExpressionには、Tokenオブジェクトを受け取るコンストラクタがあります。

このクラスのコンストラクタ本体では、Token'sコピー代入演算子を使用しています。 m_token = tok;は、デフォルトでコンパイラによって定義されます。

クラスTokenで、&が宣言されたコンストラクタでは、パラメータリストに2つのパラメータが必要です。しかし、コピー代入演算子を使用しようとすると、コンパイラがそのエラーを出すのはこのためです。 Tokenオブジェクトのコピーを割り当てて、NumberExpressionのメンバーに保存(保存)しようとしています。 Tokenconstructorは2つのパラメータを取ると宣言しているので、ctorまたはcopy ctorは使用されません。user defined constructorを宣言しても指定していないため、デフォルトのctorの宣言または定義が見つかりません。


この問題を解決するには、3つの方法があります。

  1. ヘッダー内のデフォルトまたは空のコンストラクタを提供するには、単に:

    • Token() = default;
    • Token();
    • Token() {}
  2. 使用などのようNumberExpression'sクラスのメンバ初期化子リストは述べています

    • NumberExpression::NumberExpression(Token token) : m_token(token) {...}
  3. または両方の組み合わせで使用します。また

あなたは、コンパイラによって自動的に暗黙的な変換やキャストを防止したいと、それは厳密にあなたがコンストラクタの宣言にexplicitキーワードを使用することができるようにしたい場合は、NumberExpression'sコンストラクタ に単一のオブジェクトを渡しているので、:

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; } 
}; 
+0

をenumのデフォルト初期化値? – Davar

+0

@Davar OPは、 'enum {INVALID = -1、その他、};のような他のものの前に別のenum値を追加することができます。 –

+0

それは本当ですが、enumがデフォルトで構成可能で、その動作がどのようなものか、という質問にもっと興味がありました。実際には良い質問です@Dava、 – Davar

3

m_tokenmember intializer listで直接初期化する必要があります。

参照およびconst修飾型のメンバのように、デフォルトで初期化できないメンバの場合、メンバ初期化子を指定する必要があります。

あなたの実装で

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

m_tokenは、NumberExpressionのコンストラクタの本体に割り当てられ、最初に初期化デフォルトになります。しかし、Tokenにはデフォルトコンストラクタがありません。 Tokenは、デフォルトコンストラクタを持っていないので

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

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

に相当し、コンパイラは文句を言います。そしてそうだ。

Tokenの有効なコンストラクタを使用するように変更します。

NumberExpression::NumberExpression(Token tok) : m_token(tok) {} 
関連する問題