How to fix compiler error "class has no member named X"?
Solution 1
It's pretty clear, right? Expression
doesn't have the method divide
.
Expression *tmp;
Divide d;
tmp = &d;
tmp->divide(4, 2); //tmp is an Expression*
Also... why would you do this? What's wrong with:
Divide d;
d.divide(4,2);
Solution 2
Your problem is that you are calling divide
on the variable called temp
which is a pointer to an Expression
here: tmp->divide(4, 2);
You should call divide on your d
variable.
Chris
Updated on July 05, 2022Comments
-
Chris almost 2 years
I'm currently coding an expression evaluator and have run into an issue regarding polymorphism. My class hierarchy is as follows: Divide inherits from Operator which inherits from the base class Expression. When I instantiate an Object of type Divide with base class Expression and try to access the function divide(int, int) i get the following error:
"Expression.cpp: In member function ‘int Expression::evaluate()’: Expression.cpp:37:6: error: ‘class Expression’ has no member named ‘divide’"
Here is "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
And here is "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, " "); } }
And now the "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
"Operator.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; }
"Divide.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
"Divide.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; }
and for in case the makefile
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
I have left out all the other operators such as eg. Plus, minus etc because they are all identical to what Divide is and would just complicate this question even further.
-
Chris over 11 yearsWell my stack takes an Expression* so that i dont end up using more than one stack to cater for multiple types, ie Divide, Add, Multiply, power etc. So when I parse my input equation and begin to push onto the stack, I want to be able to create a Divide or Add object that will inherit from Operator and Expression (base class).
-
Luchian Grigore over 11 years@Chris that still doesn't explain why you need the local object.
-
Chris over 11 yearsI understand what your saying, but i dont want d to call divide, i want it to be polymorphic?
-
Luchian Grigore over 11 years@Chris you have no virtual methods in your code, how can anything be polymorphic?
-
Luchian Grigore over 11 years@Chris judging by your comments, it seems there's a deeper problem, which is why I recommend this - stackoverflow.com/questions/388242/… the question (as you intend it at least, not as posted) is too broad to be answered on SO.
-
Chris over 11 yearsOk, i see what you mean, but in this case divide doesn't need to be virtual, does it? What am I not understanding about the statement Expression *tmp = new Divide(); ? Is this not possible?
-
Luchian Grigore over 11 years@Chris it is, but
tmp
is still a pointer to anExpression
...