【问题标题】:C++ inheritance - subclasses constructor call?C ++继承 - 子类构造函数调用?
【发布时间】:2011-11-02 12:52:50
【问题描述】:

我主要有以下几点:

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,为什么会出现此错误?

【问题讨论】:

    标签: c++ inheritance constructor object-slicing


    【解决方案1】:

    问题是您将临时对象传递给构造函数,但构造函数需要 -const 引用,而临时对象只能绑定到 const 引用。

    要修复它,请将参数类型更改为Expression const&amp;。顺便说一下,这与继承和多态性完全无关(但也需要 digivampire 的修复;我怀疑这只是一个错字)。

    【讨论】:

    • 修复了问题...在构造 Sum 对象之前创建了两个 Identifier 对象,以解决临时问题。
    【解决方案2】:
    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); }    
    };
    

    【讨论】:

      【解决方案3】:

      你需要Sum(Expression const &amp; first, Expression const &amp; second)

      如果没有 consts,它将无法编译 - 非 const 引用不会绑定到临时对象,例如您的临时 Identifier 对象。

      但即使那样它也不起作用 - 你最终会得到指向标识符的悬空指针。你可能会更好:

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

      但是你需要弄清楚如何在正确的时间释放东西。

      【讨论】:

        【解决方案4】:

        据我了解,向下转换(这是您想要实现的)不是自动的,您应该强制它。

        但是,要将 Identifier 转换为 Expression,您需要指向这些对象的指针。因此,如果你想保持 Sum 类的构造函数不变,你需要这样调用它:

        Identifier a("aNum1");
        Identifier b("aNum2");
        Sum *sum = new Sum(*(Expression*) &a, *(Expression*) &b);
        

        【讨论】:

          【解决方案5】:

          继承无关紧要。您应该传递 Expression 而不是 Identifier 的实例。

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

          【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-02-12
          • 2018-03-31
          • 2012-10-16
          • 1970-01-01
          相关资源
          最近更新 更多