can't initialize map of method pointers in c++ - c++

I have a function like the following:
//Parser.cpp
//...
Parser::Parser(CommandFactory & fact,
ArrayList<std::string> & expression)
{
operations["*"] = &fact.createMultiplyCommand; //error C2276
operations["/"] = &fact.createAdditionCommand; //error C2276
operations["+"] = &fact.createAdditionCommand; //error C2276
operations["%"] = &fact.createModulusCommand; //error C2276
operations["-"] = &fact.createSubtractionCommand; //error C2276
infixToPostfix(fact,expression);
}
//...
//Parser.h
//...
Parser (CommandFactory & fact,
ArrayList<std::string> & expression);
Stack<Command*> tempCommandStack;
ArrayList<Command*> postfix;
/// Destructor.
~Parser (void);
private:
//syntax is: <return_type> (*)()
//syntax for a class method is: <return_type> (<class_name> *)();
//syntax with a typedef is: typedef <return_type> (<class_name> * <typedef_name>)();
// typedef <return_type> (*<typedef_name>)()
std::map<std::string, Command * (*)()> operations;
std::map<std::string,int> precedence;
//...
It also may help to know that CommandFactory is an abstract class (what is passed in is concrete)
The error I receive is C2276: '&' : illegal operation on bound member function expression.
I don't know what I'm doing wrong exactly when I define the mapping. Any ideas?
EDIT:
//CommandFactory.h
#ifndef _COMMANDFACTORY_H_
#define _COMMANDFACTORY_H_
#include "Subtract.h"
#include "Add.h"
#include "Divide.h"
#include "Multiply.h"
#include "Modulus.h"
#include "Negation.h"
class CommandFactory
{
public:
virtual Subtract * createSubtractionCommand() = 0;
virtual Add * createAdditionCommand() = 0;
virtual Divide * createDivisionCommand() = 0;
virtual Multiply * createMultiplyCommand() = 0;
virtual Modulus * createModulusCommand() = 0;
virtual Negation * createNegationCommand() = 0;
~CommandFactory(void);
};
#endif
//StackCommandFactory.h
#ifndef _STACKCOMMANDFACTORY_H_
#define _STACKCOMMANDFACTORY_H_
#include "Add.h"
#include "Subtract.h"
#include "Divide.h"
#include "Multiply.h"
#include "Modulus.h"
#include "CommandFactory.h"
class StackCommandFactory : public CommandFactory
{
public:
virtual Subtract * createSubtractionCommand(void);
virtual Add * createAdditionCommand(void);
virtual Divide * createDivisionCommand(void);
virtual Multiply * createMultiplyCommand(void);
virtual Modulus * createModulusCommand(void);
virtual Negation * createNegationCommand(void);
protected:
Subtract * sub;
Add * add;
Divide * div;
Multiply * mul;
Modulus * mod;
Negation * neg;
};
#endif // !defined _STACKCOMMANDFACTORY_H_
//StackCommandFactory.cpp
#include "StackCommandFactory.h"
Subtract * StackCommandFactory::createSubtractionCommand(void)
{
return sub;
}
Add * StackCommandFactory::createAdditionCommand(void)
{
return add;
}
Divide * StackCommandFactory::createDivisionCommand(void)
{
return div;
}
Multiply * StackCommandFactory::createMultiplyCommand(void)
{
return mul;
}
Modulus * StackCommandFactory::createModulusCommand(void)
{
return mod;
}
Negation * StackCommandFactory::createNegationCommand(void)
{
return neg;
}

There's a few issues with your code. Mostly centring about the use of member functions rather than global functions. You try to get the member functions from an object, where you should be getting them from the class itself. ( i.e. instead of &fact.createAdditionCommand you need &CommandFactory::createAdditionCommand.) But this results in an unbound member function, which means you need to call it using (fact.*fn)() - i.e. with an object of the CommandFactory class. This is not ideal - and not what you're looking for. You are looking for a bound member function. Using these in non C++-11 applications is possible, but ugly.
You can use boost libraries to really help with that (and the code below will pretty much work unchanged other than some std to boost style changes.) If you're using C++-11 then you can use the C++-11 function objects.
Here's a complete example derived from your source:
#include <vector>
#include <map>
#include <functional>
#include <string>
struct Command {};
struct Subtract : Command {};
struct Add : Command {};
class CommandFactory
{
public:
virtual Subtract * createSubtractionCommand() = 0;
virtual Add * createAdditionCommand() = 0;
};
class StackCommandFactory : public CommandFactory
{
public:
virtual Subtract * createSubtractionCommand(void);
virtual Add * createAdditionCommand(void);
Subtract * sub;
Add * add;
};
Subtract * StackCommandFactory::createSubtractionCommand(void) { return sub; }
Add * StackCommandFactory::createAdditionCommand(void) { return add; }
class Parser
{
public:
Parser (CommandFactory & fact);
std::map<std::string, std::function<Command*()> > operations;
};
Parser::Parser(CommandFactory & fact)
{
operations["+"] = std::bind(&CommandFactory::createAdditionCommand, &fact);
operations["-"] = std::bind(&CommandFactory::createSubtractionCommand, &fact);
}
#include <iostream>
int main()
{
Add add;
Subtract sub;
StackCommandFactory command_factory;
command_factory.add = &add;
command_factory.sub= ⊂
Parser parser(command_factory);
std::cout<<"&add = "<<&add<<std::endl;
std::cout<<"Add = " << parser.operations["+"]() <<std::endl;
std::cout<<"&sub = "<<&sub<<std::endl;
std::cout<<"Sub = " << parser.operations["-"]() <<std::endl;
return 0;
}
I get the output
&add = 0x7fff58d538d8
Add = 0x7fff58d538d8
&sub = 0x7fff58d538d0
Sub = 0x7fff58d538d0
Showing that the Add object returned by going through the parser is the same as that stored into the CommandFactory. (And same for the Subtract object)

You can't do it in standard C++. For reasons have a look here & here.
EDIT:
Instead of storing "Command * (*)()" into operations, why not change "operations" value type to store "Command *" ? Or perhaps have a relook into the low-level design?

sorry try
operations["*"] = fact.createMultiplyCommand;
or
operations["*"] = fact->createMultiplyCommand;

Related

List or Array of Elements of different datatypes

I want to store 6 pointers to objects. But the Pointers can be in any order and point to different instances of (12) subclasses of one superclass, so they are possibly all of different types.
Arrays and such don't work, because the superclass is virtual.
Vectors and Tuples don't work, because the datatypes are of no specific order and are not known at compile time.
Im fairly new to C++ and I'm running out of Ideas.
Here some code to elaborate the problem:
baseclass{
getfoobar()=0;
}
subclass1{
getfoobar(){...}
}
subclass2{
getfoobar(){...}
}
---
#include <otherclasses.h>
memoryclass{
baseclass mem[6];
}
is basically what im trying.
You CAN create a vector of superclass pointers. It will achieve what you want, as it will call the overwritten function. This is of course assuming you are talking about inheritance, like:
#include <vector>
using type = ????;
class A {
virtual type foo() = 0;
}
class B : A {
type foo() override { ... }
}
class C : A {
type foo() override { ... }
}
int main(){
std::vector<A*> arr;
arr.push_back(new B);
arr.push_back(new C);
}
Now if I misunderstood and this doesn't work for some reason (i.e. they just share the function and are not actually related classes), you can do something like this, but it is not very nice:
#include <concepts>
#include <vector>
#include <functional>
using type = ?????;
template <class T> requires requires(T t){
{ t.foo() } -> std::same_as<type>;
}
std::function<type()> getFunction(T* t){
return [t](){ return t->foo(); };
}
int main(){
std::vector<std::function<type()>> arr;
arr.push_back(getFunction(new B));
arr.push_back(getFunction(new C));
}
I don't recommend this over the first option unless you have very good reason to do this.
Note: Since you didn't specify return type I winged it with ?????
Also: In the second you can replace template<class T> requires ... std::function<type()>, with just template<class T> std::function<type()>, if the compiler doesn't like #include <concepts>
You can try std::set<Superclass*>. Use pointers to your base superclass instead pointers to particular subclasses.
Actually I used std::shared_ptr<> smart pointer template to avoid raw memory management.
Example code:
#include <cstdlib>
#include <string>
#include <sstream>
#include <set>
#include <memory>
#include <iostream>
class baseclass {
public:
virtual std::string getfoobar() = 0;
};
typedef std::shared_ptr<baseclass> baseclass_ptr;
class subclass1 : public baseclass{
public:
std::string getfoobar() override {
return "from subclass1";
}
};
class subclass2 : public baseclass{
public:
std::string getfoobar() override {
return "from subclass2";
}
};
int main(int argc, char** argv) {
// Use current time as seed for random generator
std::srand(static_cast<unsigned>(std::time(nullptr)));
std::set<baseclass_ptr> container;
// Randomly generate number of elements
const int random_count = std::rand() % 10 + 1;
for (int i = 0; i < random_count; ++i) {
// Randomly create subclass1 or subclass2
if (std::rand() % 2) {
container.insert(std::make_shared<subclass1>());
}
else {
container.insert(std::make_shared<subclass2>());
}
}
// Iterate resulting container
std::cout << "size = " << container.size() << std::endl;
for (auto iterator : container) {
std::cout << "getfoobar(): " << iterator->getfoobar() << std::endl;
}
return 0;
}

How to access a atribute in a different class

I'm doing a program that just have to print value of the variables, i think the first class is working, the 'm_valor' is printed like i want , but the second class should be printing 'm_valor + m_valorAdicional', but it is printing just the value of 'm_valorAdicional':
#ifndef INGRESSO_H
#define INGRESSO_H
#include <iostream>
using namespace std;
class Ingresso
{
protected:
float m_valor;
public:
Ingresso(): m_valor(0){};
Ingresso(float valor): m_valor(valor){};
~Ingresso(){};
float getValor() const {return m_valor; };
};
class IngressoVip : public Ingresso
{
private:
float m_valorAdicional;
public:
IngressoVip(): m_valorAdicional(0){};
IngressoVip(float valor): m_valorAdicional(valor){};
~IngressoVip(){};
float getValor(){return m_valorAdicional +=m_valor;};
};
#endif
main.cpp:
#include "Ingresso.hpp"
int main()
{
Ingresso a(10);
IngressoVip b(5);
out<<"valor Ingresso: "<<a.getValor()<<endl;
cout<<"valor IngressoVip: "<<b.getValor()<<endl;
return 0;
}
I think this should be easy, but i just don't know what i have to do to work like i want.
You should use +, not +=. What += does here in this line:
return m_valorAdicional +=m_valor;
is it adds the value of m_valor to m_valorAdicional, changing the value of m_valorAdicional, and then returning this new value. If you don't want to change the values of the variables use +.

Virtual function with unkown parameter vector type

I am trying to build an optimization library in C++ for parameters optimization.
The problem and the parameters type may vary, e.g. if the problem is to minimize the Ackley Function, then we have a vector<double> of size 2 (index 0 for the x, and index 1 for the y). However, we may have problems where the parameters are integers, or even strings.
Many algorithm exist for this type of optimization, like Genetic Algorithm, Differential Evolution, etc. In most of them, once we modify the parameters based on their optimization strategy, we have to call an evaluation function that receives the parameters, and given a objective function, will return a value (fitness).
My question is how could I implement an abstract class Problem in C++ such that it contains an virtual double evaluate function in which receives as reference a vector of the generic type of the related problem? For example, user's problem should inherit Problem and he needs to specify a type T, in this case, the evaluation function should be like virtual double evaluate(const vector<T> &parameters){}.
If the strategy which I mentioned above is not feasible for C++. Please, suggest alternatives strategies.
Based on #Quentin comment and your details I would say that you could first declare Problem as a class template
#include <vector>
#include <typeinfo>
#include <iostream>
using namespace std;
template<class T>
class Problem
{
public:
Problem() {
if(typeid(T) == typeid(double)){
cout << "The problem is of type double" << endl;
}
}
virtual double evaluate(const vector<T> &decisionVariables) = 0;
};
Then you can inherit from it and override the evaluate function based on your needs. Since you mentioned Ackley Function, I implemented an AckleyFunction which inherits from Problem with type double
#include "problem.h"
#include "math.h"
using namespace std;
class AckleyFunction : public Problem<double>
{
public:
AckleyFunction() {}
double evaluate(const vector<double> &decisionVariables) override {
const double x = decisionVariables[0];
const double y = decisionVariables[1];
return -20 * exp(-0.2 * sqrt(0.5 * (pow(x, 2) + pow(y, 2)))) - exp(0.5 * (cos(2 * M_PI * x) + cos(2 * M_PI * y))) + exp(1) + 20;
}
};
The global minimum for the Ackley function is x = 0, and y = 0. You can see that bellow in the main.cpp
#include <ackleyfunction.h>
#include <memory>
using namespace std;
int main(int argc, char *argv[])
{
shared_ptr<Problem<double>> prob(new AckleyFunction());
vector<double> decisionVariables = {5.1, 3.3};
cout << "Value at coordinates (5.1, 3.3): " << prob->evaluate(decisionVariables) << endl;
decisionVariables = {0., 0.};
cout << "Value at coordinates (0.0, 0.0): " << prob->evaluate(decisionVariables) << endl;
}
Output:
The problem is of type double
Value at coordinates (5.1, 3.3): 12.9631
Value at coordinates (0.0, 0.0): 0
Would something like this do?
#include <memory>
#include <iostream>
#include <vector>
class Problem {
public:
virtual double evaluate() = 0;
};
class MyProblem : public Problem {
public:
MyProblem(const std::vector<float>& parameters) : mParameters(parameters) {}
double evaluate() override {
// Do evaluation based on mParameters
return 47.11;
}
private:
const std::vector<float>& mParameters;
};
int main() {
std::vector<float> v = {1.0f, 2.0f};
std::unique_ptr<Problem> p{new MyProblem(v)};
std::cout << p->evaluate() << '\n'; // Calls MyProblem::evaluate()
return 0;
}

resolving circular dependency when using a factory

I have the following config to evaluate and am using a factory to get an object to a subclass of MathOperation based on type.
class MathOperation {
Operation GetOperationType();
int Evaluate (config c);
}
config {
type = min
config {
type = average
int x
int y
}
config {
type = sum
int p
int q
}
...
}
For instance if x = 10, y = 20, p = 10, q = 2
the answer is min(average(10, 20), sum(10, 2)) = 12.
I am running into a circular dependency issue because each subclass of MathOperation needs to include the factory to evaluate it's subconfig and the factory ofcoruse needs to include each subclass of MathOperation. How do I resolve this?
This is what I currently have:
MathOperationFactory.h and cc
#include "average.h"
#include "min.h"
#include "sum.h"
std::unique_ptr<MathOperationObject> MakeObject(OperationType type) {
switch(type) {
case min : return MinOperation();
...
}
}
MinOperation.h and cc
#include "mathoperationfactory.h"
int Evaluate(Config c) {
int minimum = 1000; // large number.
ASSERT(config.type = min);
for(config : c) // repeated configs {
type t = c.type;
factory.MakeObject(t);
if(t.Evaluate < minimum) {
minimum = t;
}
}
return minimum;
}
The Factory doesn't need to know the subtype, it just needs to be able to new one up. One way to do this is with a Creator class whose job is to delegate the creation of the concrete object back to the class itself.
I'm using std::string here for names, but you could easily use int or Operation enum.
Something like:
#pragma once
#include <string> //
#include <map>
#include <typeinfo>
class MathOperation;
/************************************************************************/
/* MathOperation Factory */
/************************************************************************/
// Abstract Interface Type For Creator
struct CMathOperationCreator
{
virtual MathOperation* Create() = 0;
virtual ~CMathOperationCreator() {}
};
// Creator Map
std::map<std::string, CMathOperationCreator*, StringLessNoCaseCHAR>& GetMathOperationFactoryMap();
// Templated concrete creator, to be registered in the header of the concrete mathop type
template<class Derived>
struct CMathOperationConcreteCreator: public CMathOperationCreator
{
CMathOperationConcreteCreator(const std::string& theMathOperationTypeId)
{
auto aFactoryItem = GetMathOperationFactoryMap().find(theMathOperationTypeId);
if(aFactoryItem != GetMathOperationFactoryMap().end())
{
if(typeid(*aFactoryItem->second) == typeid(*this)) // avoid duplicates
return;
}
GetMathOperationFactoryMap()[theMathOperationTypeId] = this;
}
virtual MathOperation* Create() {return new Derived();}
};
//Factory Method
MathOperation* CreateMathOperation(const std::string& theMathOperationTypeId);
/**
* Macro to automatically register a MathOperation Type
*/
#define REGISTER_MathOperation( ConcreteMathOperation, name ) \
static CMathOperationConcreteCreator<ConcreteMathOperation> ConcreteMathOperation##Creator(name);
The CPP file:
// This is dumb, you don't have to do this, you just need a singleton factory that holds this map
std::map<std::string, CMathOperationCreator*, StringLessNoCaseCHAR>& GetMathOperationFactoryMap()
{
static std::map<std::string, CMathOperationCreator*, StringLessNoCaseCHAR> theMap;
return theMap;
}
MathOperation* CreateMathOperation( const std::string& theMathOperationTypeId )
{
auto aFactoryItem = GetMathOperationFactoryMap().find(theMathOperationTypeId);
if (aFactoryItem != GetMathOperationFactoryMap().end())
{
MathOperation* aObject = aFactoryItem->second->Create();
return aObject;
}
return NULL;
}
Register a class:
class MinOperation : public MathOperation {
Operation GetOperationType();
int Evaluate (config c);
};
REGISTER_MathOperation(MinOperation, "min");
Then, when you're parsing your tokens, you can query the factory for the operation:
MathOperation* pOp = CreateMathOperation(token.lowercase());
As pointed out in the comments, it's hard to be sure without seeing real code. However, most likely the issue is you are putting too many includes in the header files. if you just add #include "mathoperationfactory.h" in the cc file, you should be fine.
Also, you need to use include guards.
#pragma once makes sure that a header is only included once. Always put this as your first line in headers.

Object of abstract class type "CLASSNAME" not allowed?

I'm working on a project for my computer science class and just got introduced to classes. I have finished (I think) building the classes I need, but I'm having trouble implementing them. This is what I have for my main.cpp:
#include "ElectronicComponent.h"
#include "Resistor.h"
#include "Capacitor.h"
#include "Battery.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
const int NUMBER_OF_COMPONENTS = 7;
ElectronicComponent
*components[NUMBER_OF_COMPONENTS] =
{
new Resistor(5.0), // These are where my errors are.
new Capacitor(0.0001),
new Battery(9.0),
new Resistor(6.5),
new Battery(11.1),
new Capacitor(0.000001),
new Resistor(10000.0),
/* create more components here */
};
return 0;
}
And this is an example of one of the classes.
#include "ElectronicComponent.h"
class Resistor :
public ElectronicComponent
{
public:
Resistor(double);
virtual ~Resistor();
virtual double getValue() const = 0;
virtual std::string getUnits() const = 0;
virtual std::string to_string() const = 0;
};
.
#include "Resistor.h"
#include <string>
double value;
std::string units = "Ohm(s)";
Resistor::Resistor(double v)
{
value = v;
}
Resistor::~Resistor()
{
}
std::string Resistor::to_string() const
{
return "Resistor value (" + std::to_string(value) + " " + units + ")";
}
For each item in the ElectronicComponent array I should call the getValue and getUnits member functions and display the results.
Go through the ElectronicComponent array a second time and display the output using the ElectronicComponent item.
Here is an example (assume components is the array of ElectronicComponent
pointers):
cout << "Component " << count << " " << *components[index] << endl;
The goal is to use the hard-coded numbers to eventually get an output like this:
Component 0 Resistor value (5.000000 Ohm(s))
Component 1 Capacitor value (0.000100 Farad(s))
Component 2 Battery value (9.000000 Volt(s))
Component 3 Resistor value (6.500000 Ohm(s))
Component 4 Battery value (11.100000 Volt(s))
Component 5 Capacitor value (0.000001 Farad(s))
Component 6 Resistor value (10000.000000 Ohm(s))
Resistor's (and I assume your other ElectronicComponent derived classes) methods should not have the = 0 at the end of their declaration.
The = 0 in virtual double getValue() const = 0; and Resistor's other methods means the method is a pure virtual function. That is, it is not implemented and exists only as an interface to be overridden in derived classes. A class that contains pure virtual methods cannot be instantiated.