2

私は主に次のものを持っています:

Sum *sum = new Sum(Identifier("aNum1"), Identifier("aNum2"));

そして、私のクラスは次のとおりです。

class Table {
private:
    static map<string, int> m;    
public:
    static int lookup(string ident)
    {
        return m.find(ident)->second;
    }
    static void insert(string ident, int aValue)
    {
        m.insert(pair<string, int>(ident, aValue));
    }
};   

class Expression {
public:
    virtual int const getValue() = 0;
};

class Identifier : Expression {
private:
    string ident;
public:
    Identifier(string _ident) { ident = _ident; }
    int const getValue() { return Table::lookup(ident); }    
};

class BinaryExpression : public Expression {
protected:
    Expression *firstExp;
    Expression *secondExp;
public:
    BinaryExpression(Expression &_firstExp, Expression &_secondExp) {
        firstExp = &_firstExp;
        secondExp = &_secondExp;
    }
};

class Sum : BinaryExpression {
public:
    Sum(Expression &first, Expression &second) : BinaryExpression (first, second) {}
    int const getValue() 
    { 
        return firstExp->getValue() + secondExp->getValue();
    }
};

コンパイルすると、次のエラーが発生します。

「Sum::Sum(Identifier, Identifier)」の呼び出しに一致する関数がありません

候補は次のとおりです: Sum::Sum(Expression&, Expression&)

Identifier クラスは Expression から継承しているのに、なぜこのエラーが発生するのですか?

4

5 に答える 5

7

問題は、一時的なものをコンストラクターに渡しているが、コンストラクターは非参照を期待しているのに対しconst一時的なものは参照にのみバインドできることconstです。

これを修正するには、パラメータタイプをに変更しますExpression const&。ちなみに、これは継承やポリモーフィズムとはまったく関係ありません(ただし、digivampireの修正も必要です。これは単なるタイプミスだったと思います)。

于 2011-11-02T13:04:40.267 に答える
4
class Identifier : Expression {
private:
    string ident;
public:
    Identifier(string _ident) { ident = _ident; }
    int const getValue() { return Table::lookup(ident); }    
};

Expression の変更から Identifier を非公開で継承しています:

class Identifier : public Expression {
private:
    string ident;
public:
    Identifier(string _ident) { ident = _ident; }
    int const getValue() { return Table::lookup(ident); }    
};
于 2011-11-02T12:57:26.503 に答える
0

が必要Sum(Expression const & first, Expression const & second)です。

s がないconstとコンパイルされません-一時オブジェクトのように、非 const 参照は一時Identifierオブジェクトにバインドされません。

しかし、それでもうまくいきません - 識別子へのポインタがぶら下がることになります。次のような方が良いかもしれません:

new Sum(new Identifier("aNum1"), new Identifier("aNum2"));

ただし、適切なタイミングで解放する方法を考え出す必要があります。

于 2011-11-02T13:06:49.473 に答える
-1

私が理解しているように、ダウンキャスト(これはあなたが達成しようとしていることです)は自動ではなく、強制する必要があります。

ただし、Identifier を Expression にキャストするには、それらのオブジェクトへのポインターが必要です。したがって、Sum クラスのコンストラクターをそのまま維持したい場合は、次のように呼び出す必要があります。

Identifier a("aNum1");
Identifier b("aNum2");
Sum *sum = new Sum(*(Expression*) &a, *(Expression*) &b);
于 2011-11-02T13:54:51.233 に答える
-3

継承は関係ありません。Identifier の代わりに Expression のインスタンスを渡す必要があります。

Sum *sum = new Sum(Expression("aNum1"), Expression("aNum2"));
于 2011-11-02T12:58:27.737 に答える