I tried to implement Properties in c++. I don't no why but if I want to compile my code there are quite a lot of errors. The main Idea was, that a template class and the tamplate constructor will give the requirement Informations.
I would be grateful if somebody could help me!
Compiling Message:
pi#raspberrypi ~/dev/property $ gcc -std=c++0x -o PropertyTest2 PropertyTest2.cpp
PropertyTest2.cpp:22:16: error: expected ‘;’ at end of member declaration
PropertyTest2.cpp:22:19: error: expected unqualified-id before ‘<’ token
PropertyTest2.cpp: In function ‘int main()’:
PropertyTest2.cpp:34:20: error: use of deleted function ‘PropertyTestClass::PropertyTestClass()’
PropertyTest2.cpp:8:7: error: ‘PropertyTestClass::PropertyTestClass()’ is implicitly deleted because the default definition would be ill-formed:
PropertyTest2.cpp:8:7: error: no matching function for call to ‘Property<int>::Property()’
PropertyTest2.cpp:8:7: note: candidates are:
Property4.cpp:21:2: note: template<int (** G)(), void (** S)(int&)> Property::Property()
Property4.cpp:6:7: note: constexpr Property<int>::Property(const Property<int>&)
Property4.cpp:6:7: note: candidate expects 1 argument, 0 provided
Property4.cpp:6:7: note: constexpr Property<int>::Property(Property<int>&&)
Property4.cpp:6:7: note: candidate expects 1 argument, 0 provided
PropertyTest2.cpp:38:20: error: no matching function for call to ‘Property<int>::Set(int)’
PropertyTest2.cpp:38:20: note: candidate is:
Property4.cpp:30:7: note: void Property<T>::Set(T&) [with T = int]
Property4.cpp:30:7: note: no known conversion for argument 1 from ‘int’ to ‘int&’
Property Class (Property.cpp)
#ifndef __PROPERTY_FH__
#define __PROPERTY_FH__
template <class T>
class Property {
private:
typedef T (*TGetter)(void);
typedef void (*TSetter)(T &);
TGetter Getter;
TSetter Setter;
public:
typedef T type;
template<TGetter *G,
TSetter *S
>
Property() {
this->Getter = G;
this->Setter = S;
}
T Get(void) {
return (this->Getter)();
}
void Set(T &value) {
(this->Setter)(value);
}
};
#endif
Testing file (PropertyTest.cpp):
#ifndef __PROPERTY_TEST_FH__
#define __PROPERTY_TEST_FH__
#include <iostream>
#include "Property.cpp"
class PropertyTestClass {
private:
// ReadWrite Property for age
int _age;
int AgeGetter(void) {
return this->_age;
}
void AgeSetter(int &value) {
this->_age = value;
}
public:
// ReadWrite Property for age
Property<int> age<&PropertyTestClass::AgeGetter, &PropertyTestClass::AgeSetter>;
};
#endif
/**
* Program Entry
**/
int main() {
std::cout << "Property Test Programm\n\n";
PropertyTestClass propTest;
std::cout << "ReadWrite Property for age\n";
propTest.age.Set(5);
std::cout << propTest.age.Get() << "\n";
return 0;
}
Ok, this time fixed all the problems in your code.
Property.cpp:
#ifndef __PROPERTY_FH__
#define __PROPERTY_FH__
#include <boost/function.hpp>
template <class T>
class Property {
private:
typedef boost::function <T()> TGetter;
typedef boost::function <void(const T&)> TSetter;
TGetter Getter;
TSetter Setter;
public:
typedef T type;
Property(TGetter G, TSetter S) {
this->Getter = G;
this->Setter = S;
}
T Get(void) {
return (this->Getter)();
}
void Set(const T &value) {
(this->Setter)(value);
}
};
#endif
PropertyTests.cpp:
#ifndef __PROPERTY_TEST_FH__
#define __PROPERTY_TEST_FH__
#include <iostream>
#include <boost/bind.hpp>
#include "Property.cpp"
class PropertyTestClass {
private:
// ReadWrite Property for age
int _age;
int AgeGetter() {
return this->_age;
}
void AgeSetter(const int &value) {
this->_age = value;
}
public:
// ReadWrite Property for age
Property<int> age;
PropertyTestClass() : age(
boost::bind(&PropertyTestClass::AgeGetter, this),
boost::bind(&PropertyTestClass::AgeSetter, this, _1))
{}
};
#endif
/**
* Program Entry
**/
int main() {
std::cout << "Property Test Programm\n\n";
PropertyTestClass propTest;
std::cout << "ReadWrite Property for age\n";
propTest.age.Set(5);
std::cout << propTest.age.Get() << "\n";
return 0;
}
Output:
$ ./a.out
Property Test Programm
ReadWrite Property for age
5
Related
I have two classes : Individu and Cite and as u can see Individu is defined before
//file.hpp
#include <iostream>
#include <stdexcept>
#include <vector>
extern Cite CITE;
class Individu {
protected:
static int id;
TYPE t;
public:
Individu();
virtual ~Individu();
static int & getCompteur();
virtual void afficher(std::ostream& ) const;
virtual TYPE getType() const;
};
class Cite {
std::vector<const Individu *> tab;
public:
Cite();
~Cite();
void addPersonne(const Individu *);
int size() const;
};
std::ostream& operator<<(std::ostream&, const Individu& );
#endif
I need to add an Individu one it's instanciated to the tab vector of Cite and sisnce there is just one Cite I declared Exctern CITE Cite to work with just like that :
// file.cpp
#include <algorithm>
#include "file.hpp"
int Individu::id = 0;
Individu::Individu() {
CITE.addPersonne(*this);
id++;
}
Individu::~Individu(){
}
int& Individu::getCompteur() {
return id;
}
void Individu::afficher(std::ostream& o) const{
o << id;
}
void Personne::afficher(std::ostream& o) const {
o << nom << " " << id;
}
std::ostream& operator<<(std::ostream& o, const Individu& i ){
i.afficher(o);
return o;
}
TYPE Individu::getType() const {
throw IllegalException();
}
Cite::Cite(){
}
Cite::~Cite() {
}
void Cite::addPersonne(const Individu * i){
tab.push_back(i);
}
int Cite::size() const {
return tab.size();
}
and when I compile I got this error :
file.hpp:13:8: error: ‘Cite’ does not name a type
13 | extern Cite CITE;
| ^~~~
file.cpp: In constructor ‘Individu::Individu()’:
file.cpp:30:5: error: ‘CITE’ was not declared in this scope
30 | CITE.addPerconne(*this);
| ^~~~
make: *** [makefile:15 : build/deviant.o] Erreur 1
I understand that Cite is not yet defined so that's why I got that error , so hwo can I fix it ?
You have two issues in your code:
extern Cite CITE is declared before the class Cite is defined, so the compiler doesn't know what a Cite is at that point. You should move this declaration after the definition of Cite.
You never define CITE. An extern variable declaration is a promise to the compiler that you will define that variable later. You're essentially saying "I promise a Cite object named CITE exists even though you can't see it right now". You broke that promise by never actually creating that object. You need to define a Cite CITE somewhere (most likely in file.cpp).
I have the following code segment:
UnaryExpression.h:
#ifndef UNARYEXPRESSION_H_
#define UNARYEXPRESSION_H_
#include "Expression.h"
class UnaryExpression : public Expression {
private:
Token op;
Expression exp;
protected:
std::map<std::string, float> scope;
public:
UnaryExpression(std::map<std::string, float> &scope, Token& op, Expression& exp);
virtual ~UnaryExpression();
void evaluate();
float getReturnValue();
};
#endif /* UNARYEXPRESSION_H_ */
UnaryExpression.cpp:
#include "UnaryExpression.h"
UnaryExpression::UnaryExpression(std::map<std::string, float> &scope, Token& op, Expression& exp) : Expression(scope) {
this->op = op;
this->exp = exp;
}
UnaryExpression::~UnaryExpression() {}
void UnaryExpression::evaluate() {}
float UnaryExpression::getReturnValue() {
return this->returnResult;
}
I am constantly getting an error, but as soon as I remove Expression exp; from the constructor and private variables, the error seems to dissapear and I'm not sure why this is happening:
g++ -O0 -g3 -Wall -c -fmessage-length=0 -o "src\\UnaryExpression.o" "..\\src\\UnaryExpression.cpp"
..\src\UnaryExpression.cpp: In constructor 'UnaryExpression::UnaryExpression(std::map<std::__cxx11::basic_string<char>, float>&, Token&, Expression&)':
..\src\UnaryExpression.cpp:10:117: error: no matching function for call to 'Expression::Expression()'
10 | UnaryExpression::UnaryExpression(std::map<std::string, float> &scope, Token& op, Expression& exp) : Expression(scope) {
| ^
In file included from ..\src\UnaryExpression.h:11,
from ..\src\UnaryExpression.cpp:8:
..\src\Expression.h:18:2: note: candidate: 'Expression::Expression(std::map<std::__cxx11::basic_string<char>, float>&)'
18 | Expression(std::map<std::string, float> &scope);
| ^~~~~~~~~~
..\src\Expression.h:18:2: note: candidate expects 1 argument, 0 provided
..\src\Expression.h:13:7: note: candidate: 'Expression::Expression(const Expression&)'
13 | class Expression : public Statement {
| ^~~~~~~~~~
..\src\Expression.h:13:7: note: candidate expects 1 argument, 0 provided
Build Failed. 1 errors, 0 warnings. (took 1s.89ms)
For reference, here is the definition of Expression.h:
#ifndef EXPRESSION_H_
#define EXPRESSION_H_
#include "Statement.h"
class Expression : public Statement {
protected:
std::map<std::string, float> scope;
float returnResult;
public:
Expression(std::map<std::string, float> &scope);
virtual ~Expression();
virtual void evaluate();
virtual float getReturnValue();
};
#endif /* EXPRESSION_H_ */
The class Statement is similar to Expression, it has only a virtual method void evaluate() and a scope. When I initialize Expression, of course I pass the scope to the parent Statement class.
I am trying run the following program, But it generates compilation error:
#ifndef TEMPLATE_SUM_H_
#define TEMPLATE_SUM_H_
template<typename T>
class sum
{
public:
sum() {
val_1 = 0;
val_2 = 0;
}
sum(T a, T b) {
val_1 = a;
val_2 = b;
}
friend std::ostream& operator<<(std::ostream &, const sum<> &);
private:
T val_1, val_2;
T result() const;
};
#endif
Source file:
include <iostream>
#include "inc/sum.h"
template<typename T>
T sum<T>::result() const {
return (val_1 + val_2);
}
template<typename T>
std::ostream& operator<<(std::ostream& os, const sum<T>& obj) {
//std::ostream& operator<<(std::ostream& os, sum<T>& obj) {
os << obj.result();
return os;
}
int main()
{
sum<int> int_obj(15, 15);
sum<float> float_obj(5.2, 3.5);
std::cout << "result of int = " << int_obj << std::endl;
std::cout << "result of float = " << float_obj << std::endl;
return 0;
}
Compiling with g++ (4.4.3) it generates following error:
In file included from template.cpp:2:
inc/sum.h:18: error: wrong number of template arguments (0, should be 1)
inc/sum.h:5: error: provided for ‘template<class T> class sum’
template.cpp: In function ‘std::ostream& operator<<(std::ostream&, const sum<T>&) [with T = int]’:
template.cpp:20: instantiated from here
template.cpp:5: error: ‘T sum<T>::result() const [with T = int]’ is private
template.cpp:12: error: within this context
template.cpp: In function ‘std::ostream& operator<<(std::ostream&, const sum<T>&) [with T = float]’:
template.cpp:21: instantiated from here
template.cpp:5: error: ‘T sum<T>::result() const [with T = float]’ is private
template.cpp:12: error: within this context
1) Can Anyone please help me in identifying the error ?
Also Please suggest some links where I can find brief absolute details on how to use templates in c++.
2) I read that templatized func/classes declared in header file, and defined separately are prone to linking error. Can anyone explain/elaborate this ?
Is there any possibility of linking error in above example ?
The statement is as below:
"If a template or inline function is declared in a .h file, define it in that same file. The definitions of these constructs must be included into every .cpp file that uses them, or the program may fail to link in some build configurations."
This example can be done in some more easy way, without using overloaded operator etc. But I am trying to learn/practising templates and experimenting some features.
You need to have a separate template definition for the friend function declaration:
template<typename U>
friend std::ostream& operator<<(std::ostream &, const sum<U> &);
friend declarations do not inherit the template parameters of the enclosing class.
A simple sample source, to get started;
Calculator.h
#ifndef CALCULATOR_H
#define CALCULATOR_H
template <class TYPE>
class Calculator{
public:
Calculator();
TYPE Sum(TYPE param1, TYPE param2);
};
/**
* To avoid template related compilation error
* when templates are used in header and source files
*
* This class file has been removed from the project-source file.
* However, is present in the project folder
* Gets compiled with the header-file (being included)
*/
#include "Calculator.cpp"
#endif
Calculator.cpp
#include <iostream>
using namespace std;
#include "Calculator.h"
template <class TYPE>
Calculator<TYPE>::Calculator()
{
}
template <class TYPE>
TYPE Calculator<TYPE>::Sum(TYPE param1, TYPE param2){
cout << "Calculator::sum" << endl;
cout << param1 <<endl;
cout << param2 <<endl;
TYPE result = param1 + param2 ;
return result;
}
Main.cpp
#include <iostream>
using namespace std;
#include "Calculator.h"
int main(int argc, const char * argv[]) {
cout << "Hello, Calculator!\n";
Calculator<int> cObj;
int out = cObj.Sum(2,3);
cout << "out : " << out << endl;
Calculator<string> cObjS;
string outS = cObjS.Sum("A", "B");
cout << "outS : " << outS << endl;
cout << "Bye, Calculator!\n";
return 0;
}
Additionally, you can refer to the post, to know about how to keep the template source and header contents, and knowing about how to fix the compilation and linker issues (with reasons).
I am trying to learn how to use the Lemon parser generator, and I built a learning project. However, when I try to compile the sources, I get some strange errors from GCC. It looks like there could be some text transcribing problem or typo, but I can't find it.
I am compiling using the C++11 standard. The file "log" contains the compiler output.
I compile with
flex lexicon.l
lemon grammar.y
g++ -std=c++11 -o parser lex.yy.c grammar.c main.cpp 2> log
AST.h
#ifndef AST_H
#define AST_H
#include <string>
#include <sstream>
#include <iostream>
#include <unordered_map>
using namespace std;
string itos(int i) {
stringstream ss;
ss << i;
return ss.str();
}
class Identifier {
string name;
public:
Identifier()
: name("") {
cerr << "This initializer should never be called!" << endl;
}
Identifier(string _name)
: name(_name) {
}
string getName() {
return name;
}
};
unordered_map<string, Identifier> identifiers;
class ASTNode {
public:
virtual string toString() = 0;
};
class StatementNode: public ASTNode {
public:
virtual string toString() = 0;
};
class AssignmentNode: public StatementNode {
Identifier *id;
int newValue;
public:
AssignmentNode(Identifier *_id, int _newValue)
: id(_id),
newValue(_newValue) {
}
string toString() {
return id->getName() + " is now " + itos(newValue);
}
};
class ExpressionNode: public StatementNode {
public:
virtual string toString() = 0;
};
class ValueExpressionNode: public ExpressionNode {
int value;
public:
ValueExpressionNode(int _value)
: value(_value) {
}
string toString() {
return string("value: ") + itos(value);
}
};
class IdentifierExpressionNode: public ExpressionNode {
Identifier *id;
public:
IdentifierExpressionNode(Identifier *_id)
: id(_id) {
}
string toString() {
return string("id : ") + id->getName();
};
class PlusExpressionNode: public ExpressionNode {
ExpressionNode *lexp;
ExpressionNode *rexp;
public:
PlusExpressionNode(ExpressionNode *_lexp, ExpressionNode *_rexp)
: lexp(_lexp),
rexp(_rexp) {
}
string toString() {
return string("(") + lexp->toString() + " + " + rexp->toString() + ")";
}
};
class MinusExpressionNode: public ExpressionNode {
ExpressionNode *lexp;
ExpressionNode *rexp;
public:
MinusExpressionNode(ExpressionNode *_lexp, ExpressionNode *_rexp)
: lexp(_lexp),
rexp(_rexp) {
}
string toString() {
return string("(") + lexp->toString() + " - " + rexp->toString() + ")";
}
};
class TimesExpressionNode: public ExpressionNode {
ExpressionNode *lexp;
ExpressionNode *rexp;
public:
TimesExpressionNode(ExpressionNode *_lexp, ExpressionNode *_rexp)
: lexp(_lexp),
rexp(_rexp) {
}
string toString() {
return string("(") + lexp->toString() + " * " + rexp->toString() + ")";
}
};
class DividedByExpressionNode: public ExpressionNode {
ExpressionNode *lexp;
ExpressionNode *rexp;
public:
DividedByExpressionNode(ExpressionNode *_lexp, ExpressionNode *_rexp)
: lexp(_lexp),
rexp(_rexp) {
}
string toString() {
return string("(") + lexp->toString() + " / " + rexp->toString() + ")";
}
};
#endif
grammar.y:
%include {
#include <vector>
#include <iostream>
#include <cassert>
#include <sstream>
#include "AST.h"
int atoi (char * a) {
std::stringstream ss;
ss << a;
int i;
ss >> i;
return i;
}
Identifier* idForName(string name) {
if (identifiers.find(name) == identifiers.end()) {
identifiers[name] = Identifier(name);
}
return &(identifiers.at(name));
}
}
%token_type {char *}
%extra_argument {std::vector<StatementNode*>* statements}
start ::= statements.
statements ::= statement(stmt).
{
statements->push_back(stmt);
}
statements ::= statements NEWLINE statement(stmt).
{
statements->push_back(stmt);
}
%type statement {StatementNode*}
statement(stmt) ::= assignment(asgn).
{
stmt = asgn;
}
%type assignment {AssignmentNode*}
assignment(asgn) ::= IDENTIFIER(id) EQUALS NUMBER(num).
{
asgn = new AssignmentNode(idForName(id)), atoi(num));
}
statement(stmt) ::= expression(expr).
{
stmt = expr;
}
%type expression {ExpressionNode*}
expression(expr) ::= NUMBER(num).
{
expr = new ValueExpressionNode(atoi(num));
}
expression(expr) ::= IDENTIFIER(id).
{
expr = IdentifierExpression(idForName(id));
}
expression(expr) ::= LROUNDPAREN expression(pexpr) RROUNDPAREN.
{
expr = pexpr;
}
expression(expr) ::= expression(lexp) PLUS expression(rexp).
{
expr = new PlusExpressionNode(lexp, rexp);
}
expression(expr) ::= expression(lexp) MINUS expression(rexp).
{
expr = new MinusExpressionNode(lexp, rexp);
}
expression(expr) ::= expression(lexp) TIMES expression(rexp).
{
expr = new TimesExpressionNode(lexp, rexp);
}
expression(expr) ::= expression(lexp) DIVIDEDBY expression(rexp).
{
expr = new DividedByExpressionNode(lexp, rexp);
}
%left PLUS MINUS.
%left TIMES DIVIDEDBY.
%nonassoc LROUNDPAREN RROUNDPAREN.
lexicon.l:
%{
#include "grammar.h"
%}
%option noyywrap
%%
[A-Za-z_][A-Za-z0-9]* return IDENTIFIER;
[0-9]+ return NUMBER;
"=" return EQUALS;
"+" return PLUS;
"-" return MINUS;
"*" return TIMES;
"/" return DIVIDEDBY;
"(" return LROUNDPAREN;
")" return RROUNDPAREN;
\n return NEWLINE;
%%
main.cpp
#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
#include <cstring>
#include "AST.h"
using namespace std;
void* ParseAlloc(void* (*allocProc)(size_t));
void Parse(void*, int, char *, vector<StatementNode*>*);
void ParseFree(void*, void(*freeProc)(void*));
int yylex();
extern char * yytext;
int main() {
vector<StatementNode*> statements;
vector<char*> strpointers;
void* parser = ParseAlloc(malloc);
while (int lexcode = yylex()) {
char *tmp = (char*)malloc((strlen(yytext)+1)*sizeof(char));
strcpy(tmp, yytext);
Parse(parser, lexcode, tmp, &statements);
strpointers.push_back(tmp);
}
for (vector<StatementNode*>::iterator i = statements.begin(); i != statements.end(); i++) {
cout << (*i)->toString() << endl;
}
Parse(parser, 0, NULL, &identifiers);
ParseFree(parser, free);
for (vector<char*>::iterator i=strpointers.begin(); i != strpointers.end(); i++) {
free(*i);
}
return 0;
}
log:
grammar.c:105:44: error: ‘constexpr’ needed for in-class initialization of static data member ‘const IdentifierExpressionNode::YYMINORTYPE IdentifierExpressionNode::yyzerominor’ of non-integral type [-fpermissive]
grammar.c:173:1: error: in-class initialization of static data member ‘const unsigned char IdentifierExpressionNode::yy_action []’ of incomplete type
grammar.c:179:1: error: in-class initialization of static data member ‘const unsigned char IdentifierExpressionNode::yy_lookahead []’ of incomplete type
grammar.c:187:1: error: in-class initialization of static data member ‘const signed char IdentifierExpressionNode::yy_shift_ofst []’ of incomplete type
grammar.c:194:1: error: in-class initialization of static data member ‘const signed char IdentifierExpressionNode::yy_reduce_ofst []’ of incomplete type
grammar.c:199:1: error: in-class initialization of static data member ‘const unsigned char IdentifierExpressionNode::yy_default []’ of incomplete type
grammar.c:257:28: error: ‘constexpr’ needed for in-class initialization of static data member ‘FILE* IdentifierExpressionNode::yyTraceFILE’ of non-integral type [-fpermissive]
grammar.c:258:30: error: ‘constexpr’ needed for in-class initialization of static data member ‘char* IdentifierExpressionNode::yyTracePrompt’ of non-integral type [-fpermissive]
grammar.c:296:1: error: in-class initialization of static data member ‘const char* const IdentifierExpressionNode::yyTokenName []’ of incomplete type
grammar.c:316:1: error: in-class initialization of static data member ‘const char* const IdentifierExpressionNode::yyRuleName []’ of incomplete type
grammar.c:642:1: error: in-class initialization of static data member ‘const IdentifierExpressionNode::<anonymous struct> IdentifierExpressionNode::yyRuleInfo []’ of incomplete type
grammar.c:842:13: error: ‘static void IdentifierExpressionNode::yy_accept(IdentifierExpressionNode::yyParser*)’ cannot be overloaded
grammar.c:644:13: error: with ‘static void IdentifierExpressionNode::yy_accept(IdentifierExpressionNode::yyParser*)’
grammar.c:1025:1: error: expected ‘}’ at end of input
grammar.y: In static member function ‘static void IdentifierExpressionNode::yy_reduce(IdentifierExpressionNode::yyParser*, int)’:
grammar.y:51:69: error: cannot call member function ‘Identifier* IdentifierExpressionNode::idForName(std::string)’ without object
grammar.y:51:96: error: cannot call member function ‘int IdentifierExpressionNode::atoi(char*)’ without object
grammar.y:51:97: error: expected ‘;’ before ‘)’ token
grammar.y:63:68: error: cannot call member function ‘int IdentifierExpressionNode::atoi(char*)’ without object
grammar.y:68:70: error: cannot call member function ‘Identifier* IdentifierExpressionNode::idForName(std::string)’ without object
grammar.y:68:71: error: ‘IdentifierExpression’ was not declared in this scope
grammar.c: At global scope:
grammar.c:1025:1: error: expected unqualified-id at end of input
main.cpp:9:7: error: expected nested-name-specifier before ‘namespace’
main.cpp:9:7: error: expected unqualified-id before ‘namespace’
main.cpp:9:7: error: expected ‘;’ before ‘namespace’
main.cpp:9:7: error: expected unqualified-id before ‘namespace’
main.cpp:16:15: error: storage class specified for ‘yytext’
main.cpp:40:1: error: expected ‘}’ at end of input
main.cpp: In member function ‘int IdentifierExpressionNode::main()’:
main.cpp:33:37: error: no matching function for call to ‘IdentifierExpressionNode::Parse(void*&, int, NULL, std::unordered_map<std::basic_string<char>, Identifier>*)’
main.cpp:33:37: note: candidate is:
main.cpp:12:6: note: void IdentifierExpressionNode::Parse(void*, int, char*, std::vector<StatementNode*>*)
main.cpp:12:6: note: no known conversion for argument 4 from ‘std::unordered_map<std::basic_string<char>, Identifier>*’ to ‘std::vector<StatementNode*>*’
main.cpp: At global scope:
main.cpp:40:1: error: expected unqualified-id at end of input
You have a missing curly brace in AST.h.
The first error message you received indicated that the given declaration wasn't allowed "in-class". This is the clue that you need. It looks like it's not supposed to be in a class, so why does the compiler think that it is? This should make you strongly suspect that somewhere earlier there is a missing closing brace. Indeed, if you look in your AST.h file, you have this:
class IdentifierExpressionNode: public ExpressionNode {
Identifier *id;
public:
IdentifierExpressionNode(Identifier *_id)
: id(_id) {
}
string toString() {
return string("id : ") + id->getName();
};
You need to add a missing closing brace to toString.
In general, when you get a huge long list of error messages like this, you should look most closely at just the first error or the first few, and ignore the rest. They are all likely from the same cause, and the further you read past the point that things started going wrong, the less useful further error messages become.
Hi I am making a simple stack class in C++ and am new to C++. I am having a few errors that I cannot figure out what they mean. Some help would be greatly appreciated! Here is my code:
Stack.h
#ifndef SStack
#define SStack
#include <cstdlib>
#include <string>
class SStack
{
public:
// Constructor
SStack( int cap);
// Copy Constructor
SStack( const SStack& s );
~SStack( );
void push ( const std::string& s);
std::string& pop ();
std::string& top () const;
bool IsEmpty () const;
int size() const;
int getCapacity() const;
// NONMEMBER FUNCTIONS for the bag class
// Precondition: s1.size( ) + s2.size( ) <= s1.Capacity.
// Postcondition: The stack returned is the union of s1 and s2.
SStack operator +(const SStack& s2);
private:
int Capacity; // Capacity is the maximum number of items that a stack can hold
std::string *DynamicStack;
int used; // How many items are stored in the stack
};
#endif
Stack.cpp
#include "SStack.h"
#include <string>
#include <cstdlib>
#include <iostream>
using namespace std;
class SStack
{
public:
void SStack(int cap){
DyanmicStack = new string[cap];
Capacity = cap;
used = -1;
}
void SStack(const SStack& s){
DyanmicStack = new string[cap];
}
~SStack( ){
delete(DynamicStack);
}
void push(const string& s){
DynamicStack[used] = s;
used++;
}
string& pop(){
if(used==-1){
cout << "Error stack is empty";
return " ";
}
else{
used--;
return DynamicStack[used+1];
}
}
string& top () const{
if(used==-1){
cout << "Error stack is empty";
return " ";
}
else{
return DynamicStack[used];
}
}
bool isEmpty(){
return (used==-1);
}
int size(){
return (used+1);
}
int getCapacity(){
return Capacity;
}
private:
int Capacity; //How much the stack can hold
string* DynamicStack;
int used; //objects in the stack
};
And here are the errors:
SStack.h:11: error: expected unqualified-id before ‘int’
SStack.h:11: error: expected `)' before ‘int’
SStack.h:13: error: expected unqualified-id before ‘const’
SStack.h:13: error: expected `)' before ‘const’
SStack.h:14: error: expected class-name before ‘(’ token
SStack.h:25: error: ISO C++ forbids declaration of ‘operator+’ with no type
SStack.h:25: error: ISO C++ forbids declaration of ‘s2’ with no type
SStack.h:8: error: an anonymous union cannot have function members
SStack.h:31: error: abstract declarator ‘<anonymous class>’ used as declaration
SStack.cpp:11: error: expected unqualified-id before ‘int’
SStack.cpp:11: error: expected `)' before ‘int’
SStack.cpp:17: error: expected unqualified-id before ‘const’
SStack.cpp:17: error: expected `)' before ‘const’
SStack.cpp:21: error: expected class-name before ‘(’ token
SStack.cpp: In member function ‘std::string&<anonymous class>::pop()’:
SStack.cpp:33: error: invalid initialization of non-const reference of type ‘std::string&’ from a temporary of type ‘const char*’
SStack.cpp: In member function ‘std::string&<anonymous class>::top() const’:
SStack.cpp:44: error: invalid initialization of non-const reference of type ‘std::string&’ from a temporary of type ‘const char*’
SStack.cpp: At global scope:
SStack.cpp:8: error: an anonymous union cannot have function members
SStack.cpp:70: error: abstract declarator ‘<anonymous class>’ used as declaration
Your include guard has the same name as your class. Remember that the preprocessor is a very simplistic search/replace feature.
#define SStack
class SStack
{
public:
// Constructor
SStack( int cap);
becomes:
#define SStack
class
{
public:
// Constructor
( int cap);
One pattern is to name it the same as your header's filename, such as STACK_H.
First of all, as was already noted, the header guard is broken.
Now, onto the actual problems:
You have misunderstood how class definition works. Your header is largely correct, what is wrong is your .cpp file. You are redefining class that you already have defined inside the header file. The proper way to provide implementation of member function is this
void SStack::SStack(const SStack& s){
DyanmicStack = new string[cap];
} or in for clearer example:
void SStack::push(const string& s){
DynamicStack[used] = s;
used++;
}.
Basically, you have to prepend the classes's name before the function name.
Also, just by copy pasting this I've noticed typo in your code (see if you can spot it ;-) ), and I would recommend rethinking the design, even if it is just an exercise.
I realized the class Pila(stack) some times ago, this is my solution:
(sorry but I'm new.. so I don't know how to indent the code here)
file: pila.h
//nodo is the type of elements that class pila contains.
struct nodo
{
int dato;
nodo* precedente;
};
class pila
{
private:
nodo* ultimo;
public:
pila();
void push(int numero);
int pop();
};
file: pila.cpp
#include <iostream>
#include"pila.h"
using namespace std;
pila::pila()
{
ultimo=NULL; // punta all'ultimo nodo inserito
}
void pila::push(int numero)
{
nodo* nuovo;
nuovo=new struct nodo;
nuovo->dato=numero;
if(ultimo==NULL)
{
nuovo->precedente=NULL;
ultimo=nuovo;
}
else
{
nuovo->precedente=ultimo;
ultimo=nuovo;
}
}
int pila::pop()
{
if (ultimo==NULL)
{
return 0;
}
else
{
int prelevato=ultimo->dato;
ultimo=ultimo->precedente;
return prelevato;
}
}