【问题标题】:How to fix compiler error "class has no member named X"? [closed]如何修复编译器错误“类没有名为 X 的成员”? [关闭]
【发布时间】:2012-09-22 16:20:42
【问题描述】:

我目前正在编写一个表达式求值器并且遇到了一个关于多态性的问题。 我的类层次结构如下: Divide 继承自 Operator,Operator 继承自基类 Expression。当我使用基类 Expression 实例化 Divide 类型的 Object 并尝试访问函数 divide(int, int) 时,出现以下错误:

“Expression.cpp:在成员函数‘int Expression::evaluate()’中: Expression.cpp:37:6: 错误:‘class Expression’没有名为‘divide’的成员”

这里是“Expression.h”

#ifndef EXPRESSION_H
#define EXPRESSION_H
#include <string>
using namespace std;
class Operator;
class Divide;
class Expression 
{
  protected:
    char **ana, *exp;

  public:
   Expression();
   ~Expression();
   Expression(char* ex);
   int evaluate();
   void tokenize();

    class EmptyException
    {
       public:
     EmptyException(string a){reason = a;};
     string getReason() const{return reason;};
       private:
     string reason;
    };

};

#endif

这里是“Expression.cpp”

#include "Expression.h"
#include "Stack.h"
#include "Queue.h"
#include "Node.h"
#include <iostream>
#include <cstring>
#include <stdio.h>
#include <ctype.h>
#include "Operator.h"
#include "Divide.h"

Expression::Expression()
{

} 

Expression::~Expression()
{
   delete [] exp;
}

Expression::Expression(char* ex)
{
   exp = ex;
   //tokenize();

}

int Expression::evaluate()
{
  Stack stack;

  Expression *tmp;
  Divide d;
  tmp = &d;
  tmp->divide(4, 2);
  stack.push(tmp);
   tmp = stack.pop();

 }

 void Expression::tokenize()
 {  
   int space = 0;

   for(int i  =0 ; i < strlen(exp); i++)
   {
     if(exp[i] == ' ')
     space++;
   } 

   char ** ana = new char*[space + 1];
   ana[0] = strtok(exp, " ");

   for(int i = 1 ; i < space + 1; i++)
   {        
   ana[i]= strtok (NULL, " ");
   }

  } 

现在是“operator.h”

#ifndef OPERATOR_H
#define OPERATOR_H
#include "Expression.h"

using namespace std;

class Operator : public Expression
{
  protected:
    bool unary, binary;
  public:
    Operator();
    bool isUnary() const;
    bool isBinary() const;
};

#endif

“运算符.cpp”

#include "Operator.h"
#include <string>
#include <cmath>
#include "Expression.h"

Operator::Operator()
{

}

bool Operator::isUnary() const 
{
      if(unary)
    return true;
      else
    return false;

}

bool Operator::isBinary() const 
{
      if(binary)
    return true;
      else
    return false; 
}

“除法.h”

#ifndef DIVIDE_H
#define DIVIDE_H

#include <string>
#include "Operator.h"
class Expression;
using namespace std;


class Divide : public Operator
{
        private:
      char id;
    public:
        Divide();
        Divide(char);
        int divide(int a, int b);
        char identity() const;
};

#endif

“除法.cpp”

#include "Divide.h"

int Divide::divide(int a, int b)
{
  return a/b;
}

Divide::Divide(char _id)
{
 id = _id; 
}

char Divide::identity() const
{
  return id;
}

如果生成文件

main: Expression.o Equation.o Operator.o Divide.o Stack.o Queue.o main.o
   g++ -static main.o Equation.o Expression.o Operator.o Divide.o Stack.o Queue.o -o main

main.o : main.cpp 
        g++ -c main.cpp 

Equation.o : Equation.cpp Equation.h
    g++ -c Equation.cpp

Expression.o : Expression.cpp Expression.h 
    g++ -c Expression.cpp 

Operator.o : Operator.cpp Operator.h Expression.h 
    g++ -c Operator.cpp 

Divide.o : Divide.cpp Divide.h Operator.h
    g++ -c Divide.cpp 

Stack.o : Stack.cpp Stack.h Node.h
    g++ -c Stack.cpp

Queue.o : Queue.cpp Queue.h Node.h
    g++ -c Queue.cpp

我省略了所有其他运算符,例如 eg。加号,减号等,因为它们都与 Divide 相同,只会使这个问题更加复杂。

【问题讨论】:

    标签: c++ object inheritance polymorphism virtual


    【解决方案1】:

    很清楚,对吧? Expression 没有 divide 的方法。

    Expression *tmp;
    Divide d;
    tmp = &d;
    tmp->divide(4, 2); //tmp is an Expression*
    

    还有……你为什么要这样做?有什么问题:

    Divide d;
    d.divide(4,2);
    

    【讨论】:

    • 好吧,我的堆栈采用一个表达式*,因此我最终不会使用多个堆栈来满足多种类型,即除法、加法、乘法、幂等。所以当我解析我的输入方程和开始压入堆栈,我希望能够创建一个从运算符和表达式(基类)继承的 Divide 或 Add 对象。
    • @Chris 仍然没有解释为什么你需要本地对象。
    • @Chris 从您的 cmets 来看,似乎存在更深层次的问题,这就是我推荐这个的原因 - stackoverflow.com/questions/388242/… 这个问题(至少按照您的意图,而不是发布的那样)太广泛了在 SO 上回答。
    【解决方案2】:

    您的问题是您在名为temp 的变量上调用divide,这是一个指向Expression 的指针:tmp-&gt;divide(4, 2); 您应该在您的d 变量上调用divide。

    【讨论】:

    • 我明白你的意思,但我不想 d 调用 divide,我希望它是多态的?
    • @Chris 你的代码中没有虚拟方法,怎么可能是多态的?
    • 好的,我明白你的意思了,但在这种情况下,divide 不需要是虚拟的,不是吗?我对语句 Expression *tmp = new Divide(); 不了解什么? ?这不可能吗?
    • @Chris 是,但 tmp 仍然是指向 Expression 的指针...
    猜你喜欢
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多