I'm putting objects in a map(code below) when i try to get it the object is empty!
Server s;
s.port = 5400;
commandsMap.insert(std::pair<string,Command>("openDataServer",s));
Server is inherent from Command
class Server: public Command{
public:
static map<string,Varinfo> symbolList;
static map<string,Command> commandsMap;
bool stop = false;
int port;
int execute(vector<string> inputs);
static int lstn(int socketfd,sockaddr_in address);
};
and here is command
class Command{
public:
Command();
int execute(vector<string> inputs);
};
and here I'm trying to find the values that I pushed up there, but the object is from class Command and its empty!
auto it = commandsMap.find(commands[index]);
if ( it != commandsMap.end() ) {
index += it->second.execute(commands);
}
note: commands[index] returns a string
and when I debug after pushing the object I see it right inside the map, but when I use find iterator it->second returns empty object Command
any ideas?
thanks
Update:
I think the problem is that the object that the map finds its not a server object, I want to push in the map many types of classes that inherts Command, and each one to run its own execute() and to have its own fields
the Command that the map returns is returned as Command Class, it should return as Server
final Question:
I want to use a shared pointer as a solution
I have classes like Server that inherits from Command, I want to put them inside a map, and then run thier own execute() as shown upthere
The problem is that you are storing your Server object as a map value of base type Command. This operation slices from Server instance all the fields and leaves only those from base class.
Usual solution to this problem is to store pointer to base class in the map instance of the bare object, and also use virtual interface. So I suggest you to make int execute(vector<string> inputs); virtual and override it in the Server derived class with its specific implementation. In the map use std::unique_ptr<Command> as the value:
https://coliru.stacked-crooked.com/a/df5fa3a97f897977
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <memory>
using namespace std;
struct Varinfo{};
struct sockaddr_in{};
class Command{
public:
Command() {}
virtual int execute(vector<string> inputs) {
std::cout << "From: Command" << std::endl;
return 0;}
};
class Server: public Command{
public:
static map<string,Varinfo> symbolList;
static map<string,Command> commandsMap;
bool stop = false;
int port;
int execute(vector<string> inputs) override {
std::cout << "From: server: port = " << port << std::endl;
return 0;}
static int lstn(int socketfd,sockaddr_in address){return 0;}
};
int main()
{
std::map<std::string, std::unique_ptr<Command>> commandsMap;
auto server_ptr = std::make_unique<Server>();
server_ptr->port = 5400;
commandsMap.emplace("openDataServer", std::move(server_ptr));
// or: commandsMap.emplace("openDataServer", std::make_unique<Server>(...));
int index = 0;
std::vector<std::string> commands = {"openDataServer"};
auto it = commandsMap.find(commands[index]);
if ( it != commandsMap.end() ) {
index += it->second->execute(commands);
}
}
Related
#include <iostream>
#include <vector>
using namespace std;
class Test
{
private:
int ID;
string name;
public:
Test(int ID, string name);
};
Test::Test(int ID, string name)
{
this->ID = ID;
this->name = name;
}
int main()
{
vector<Test *> test_vect;
Test *ptr = new Test(100, "John");
test_vect.push_back(ptr);
cout << ptr->ID << endl;
return 0;
}
This is a simple code I'm trying.
I want to access to the data that I stored in vector.
I thought it would be accessible by using -> just like vector of struct but I can't. So I want to know how to load the data in class.
In addition, I thought sending data to heap section using new would make it accessible at any time I want regardless of whether it is private or public, but it seems like it is not possible.
Can you explain how it works?
(I don't even fully understand how class work, so detailed explanation would be very appreciated. Thx!)
A private variable cannot be accessed by code outside the class definition. (There are exceptions with friend)
ptr->ID does not work because main is outside the class definition.
This can be fixed by using a getter method.
#include <iostream>
#include <vector>
using namespace std;
class Test
{
private:
int _ID;
string _name;
public:
int ID() {return _ID;}
string name() {return _name;}
Test(int param_ID, string param_name);
};
Test::Test(int param_ID, string param_name)
{
_ID = param_ID;
_name = param_name;
}
int main()
{
vector<Test *> test_vect;
Test *ptr = new Test(100, "John");
test_vect.push_back(ptr);
cout << ptr->ID() << endl;
return 0;
}
The above example shows the getter methods ID() and name() which return the data members _ID and _name respectively.
ID() is allowed to access _ID because ID() is part of the class definition. name() is allowed to access _name because name() is part of the class definition.
Note: I would still consider this code to be flawed because it creates a new object on the heap, but does not delete it. You should also look up the keywords new and delete to see how they operate together.
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.
I have Application singleton wich has method
void addHandler(const std::string& command, std::function<std::string (const std::string&)> handler)
I want to create a lot of cpp files with handlers like this
//create_user_handler.cpp
Application::getInstance()->addHandler("create_user", [](std::string name) {
UserPtr user = User::create(name);
return user->toJson();
});
How automatically call this from my cpp files?
I try to change from void addHandler to bool addHandler and than use
namespace {
bool b = Application::getInatance()->addHandler......
}
but it didn't work for me
Udate
It works now, but could it be done in a better way, without unused bool variable?
Make use of static class instantiation.
Pseudo code -
Add a registrator class.
class Registrator {
template <typename Func>
Registrator(const std::string& name, Func handler) {
Application::getInstance()->addHandler(name, handler);
}
};
And in each cpp file, create a static class object:
test.cpp
static Registrator test_cpp_reg("create_user", [](std::string name) {
UserPtr user = User::create(name);
return user->toJson();
});
I assume that addHandler() should return bool? Otherwise, you can't assign to the bool variable.
To remove the bool return of addHandler, make the call from the constructor of some other class that you in turn instantiate statically.
This kind of code can work, but it is tricky. The problem is that in C/C++, the order of static-storage initializers is undefined. So while a static initializer is allowed to call any code, if that code references as-yet-uninitialized data, it will fail. And unfortunately the failure is non-deterministic. It might work for a while, and then you change some compiler flag or module order, and splat!
One trick is to implement the instance state of getInstance() using a dumb pointer, because that is always initialized to zero (null) before any of the static initializers fire. For example, the following code will print "Added foo" before main starts:
#include <string>
#include <functional>
#include <map>
#include <iostream>
class Application {
public:
static Application* getInstance() {
// Not thread-safe!
if (instance == 0) {
instance = new Application;
}
return instance;
}
typedef std::function<std::string(const std::string&)> HANDLER;
typedef std::map<std::string, HANDLER> HANDLER_MAP;
bool addHandler(const std::string& command, HANDLER handler) {
handlerMap.insert(HANDLER_MAP::value_type(command, handler));
std::cout << "Added " << command << "\n";
return true;
}
HANDLER_MAP handlerMap;
static Application* instance;
};
Application* Application::instance;
std::string myHandler(const std::string&) { return ""; }
bool b = Application::getInstance()->addHandler("foo", myHandler);
int main()
{
return 0;
}
I'm new to c++ and I'm writing a program that executes certain commands. My program is supposed to have about 200 commands and using strcmp to check if the string is one among the command seems to be slow and inaccurate to me. I'm wondering if there's a function that could call the given input directly as a command.
For example:
void main() {
char test[60], param[10];
std::cin >> test >> param;
callFunction(test, param);
}
NOTE : I've done some search already and found a way using maps, but what if the number of arguments for each function differs? Any help would be appreciated, thanks!
It would be a good coding practice to create a class for each command and inherit those classes from a common base class with a virtual function taking a vector of arguments. In your case the arguments are strings, so the command processing methods can take a vector of strings as arguments and return e.g. program exit code. Then comes a map, more specifically a hash table which is unordered_map in C++ because ordered iteration doesn't seem needed here. In that unordered_map the keys are lowercase command names and values are pointers to the instance of the class processing that command. The source code example is below:
#include <unordered_map>
#include <string>
#include <cstdint>
#include <vector>
#include <iostream>
#include <memory>
enum class ExitCode : int32_t
{
OK = 0,
WRONG_USAGE = 1,
// Change the values below to your specific error (exit) codes
SOME_ERROR = 2,
OTHER_ERROR = 3
};
class CommandProcessor
{
public:
virtual ExitCode Go(const std::vector<std::string>& parameters) = 0;
};
class FooCommandProcessor : public CommandProcessor
{
public:
virtual ExitCode Go(const std::vector<std::string>& parameters) override
{
// Implement processing of Foo command here
return ExitCode::OK;
}
};
class BarCommandProcessor : public CommandProcessor
{
virtual ExitCode Go(const std::vector<std::string>& parameters) override
{
// Implement processing of Bar command here
return ExitCode::OK;
}
};
// Implement classes processing the other commands here
class CommandSelector
{
typedef std::unordered_map<std::string, std::shared_ptr<CommandProcessor>>
StringCommandProcessorMap;
StringCommandProcessorMap _scpm;
template <class CP> void RegisterCommand(const std::string& command)
{
_scpm.insert(StringCommandProcessorMap::value_type(
command, std::shared_ptr<CommandProcessor>(new CP())));
}
public:
CommandSelector()
{
RegisterCommand<FooCommandProcessor>("foo");
RegisterCommand<BarCommandProcessor>("bar");
// Register the rest of your commands here
}
ExitCode InvokeCommand(const std::string& command,
const std::vector<std::string>& parameters)
{
std::string lowercaseCommand;
for (int i = 0; i < int(command.size()); i++)
{
lowercaseCommand.push_back(::tolower(command[i]));
}
StringCommandProcessorMap::iterator it = _scpm.find(lowercaseCommand);
if (it == _scpm.end())
{
std::cout << "Unknown command: " << lowercaseCommand << std::endl;
return ExitCode::WRONG_USAGE;
}
return it->second->Go(parameters);
}
};
int main(int argc, char* argv[])
{
if (argc < 2)
{
std::cout << "Usage: <your_exe_name> <command> [arguments]" << std::endl;
return int(ExitCode::WRONG_USAGE);
}
std::string command(argv[1]);
std::vector<std::string> parameters;
for (int i = 2; i < argc; i++)
{
parameters.push_back(std::string(argv[i]));
}
CommandSelector cs;
ExitCode ec = cs.InvokeCommand(command, parameters);
return int(ec);
}
You can call exec methods with the required argument to run your commands
Checkout: http://linux.die.net/man/3/exec
Check out the Command pattern:
https://en.wikipedia.org/wiki/Command_pattern
http://www.oodesign.com/command-pattern.html
Encapsulate all commands/functions in their own objects. Most probably, you don't need 200 different Command classes but only a few, grouping similar function calls with same purpose and argument count and type.
Then make a map of strings to these command objects. Command objects all have the same interface and the differences in the argument count and type of the original fnctions is encapsulated within.
A table of function calls (or similar). If speed is important, using std::unordered_map to do something like:
std::unordered_map<std::string, function> cmds;
...
cmds["mycommand"] = myCommandFunction();
I personally have written a dozen different programs with static array tables of string + function pointer as well, and just using a plain loop to iterate over the array - it's usually not the slowest part of the design [if speed matters, profile your code to see where it's taking time, then optimise, but start by writing clear and simple code, do not make the code more complex simply because you think it may be a large portion of time, before you have measured it]
An example of using std::map and function pointers [in this case lambda functions] can be found here:
https://github.com/Leporacanthicus/lacsap/blob/master/builtin.cpp#L972
Example of my comment:
#include <string>
#include <unordered_map>
#include <iostream>
typedef void(*commandPtr)(const char* args);
std::unordered_map <std::string, commandPtr> commands;
void someCommand(const char* args)
{
std::cout << "some command with args : " << args << std::endl;
}
int main()
{
commands.insert(std::make_pair("someCommand", someCommand)); // add a command to the map
std::string command, args;
std::cin >> command >> args;
if (commands.find(command) == commands.end()) // the command doesn't exist
std::cout << "Command doesn't exist";
else
commands.find(command)->second(args.c_str()); // call the command with args
std::cin.get();
return 0;
}
This allows for just one abitrary argument though.
In the below programme i use one boolean variable named check , which is being accessed inside main function by two objects of Tst1 and Test2 . But the value of check variable is not maintained in the programme . we can use static but i want to know some alternative way ..could anyone give me some hints on it ?
Thanks in advance .
Inside jointdeatils.h
#pragma once
class Jointdetails
{
public:
Jointdetails(void);
~Jointdetails(void);
bool check;
};
Inside jointdeatils.cpp
#include "Jointdetails.h"
Jointdetails::Jointdetails(void)
{
check = false ;
}
Jointdetails::~Jointdetails(void)
{
}
Inside analyzer.h
#pragma once
#include "Jointdetails.h"
class Analyzer
{
public:
Analyzer(void);
Jointdetails* GetJointDetails();
Jointdetails* m_ptheCTJointDetails;
~Analyzer(void);
};
Inside analyzer.cpp
#include "Analyzer.h"
#include "stddef.h"
Analyzer::Analyzer(void)
{
m_ptheCTJointDetails = new Jointdetails();
}
Analyzer::~Analyzer(void)
{
}
Jointdetails* Analyzer::GetJointDetails()
{
if(m_ptheCTJointDetails)
return m_ptheCTJointDetails;
else
return NULL;
}
Inside Test1.h
#pragma once
#include "Analyzer.h"
class Tst1
{
public:
Tst1(void);
Analyzer *analyzer1 ;
public:
~Tst1(void);
};
Inside Test1.cpp
#include "Tst1.h"
Tst1::Tst1(void)
{
analyzer1 = new Analyzer ;
}
Tst1::~Tst1(void)
{
}
Inside Test2.h
#pragma once
#include "Analyzer.h"
class Test2
{
public:
Test2(void);
Analyzer *analyzer2 ;
public:
~Test2(void);
};
Inside Test2.cpp
#include "Test2.h"
Test2::Test2(void)
{
analyzer2 = new Analyzer ;
}
Test2::~Test2(void)
{
}
Inside main.cpp
#include "Test2.h"
#include "Tst1.h"
#include "stdio.h"
int main()
{
Tst1 *test1 = new Tst1 ; //check = false
Test2 *test2 = new Test2 ; //check = false
test1->analyzer1->GetJointDetails()->check = true ;
if(test2->analyzer2->GetJointDetails()->check )
printf("Check value is changed");
else
printf("Check value is not changed");
return 0 ;
}
There are only two possible ways to do so:
Use static storage data
Pass automatic or dynamic storage data as parameters to destination functions/ctors
Way #1 is more handy as you can access such data directly from any function. But it shall be considered as bad design because it almost the same thing as evil global variables.
Way #2 is more correct (see answer by justin for example) but could be a bit irritating - you will need to pass required data as parameter to each required function and/or store data as class data member. Not a pleasant work in case of many classes/nested calls.
Nevertheless, if you don't care on drawbacks of way #1 consider singleton-on-demand concept. It allows to use static data in more dynamic way - create on demand, share access by several users and destroy when nobody use it anymore. See example (several details, includes etc skipped for brevity):
JointDetails.h
class JointDetails
{
// Actual class definition
// ...
public:
// Function accessing to JointDetails instance
static std::shared_ptr<JointDetails> Get();
};
JointDetails.cpp
std::shared_ptr<JointDetails> JointDetails::Get()
{
static std::weak_ptr<JointDetails> s_trackInstance;
if(s_trackInstance.expired())
{
auto instance = std::make_shared<JointDetails>();
s_trackInstance = instance;
return instance;
}
return s_trackInstance.lock();
}
Analyzer.h
// All instances of Analyzer share the same instance of JointDetails.
// But JointDetails instance is created dynamically only when first instance of
// Analyzer is created and destoyed when the last instance of Analyzer is destroyed.
class Analyzer
{
std::shared_ptr<JointDetails> m_details;
public:
Analyzer(): m_details(JointDetails::Get()) {}
const JointDetails& GetDetails() const { return *m_details; }
};
You're either going to have to make check static, or JointDetails a singleton (which also uses the static keyword).
If you make check static, you are saying that all instances of JointDetails have the same check.
If you make JointDetails a singleton, then you're saying that every reference to a JointDetails object is the same object, so your Tst1 and your Test2 will both have a pointer to the same object.
I think the latter is what you're looking for:
Jointdetails.h
#pragma once
class Jointdetails
{
public:
~Jointdetails(void);
bool check;
static Jointdetails* getInstance();
private:
Jointdetails(void);
};
Jointdetails.cpp
#include "Jointdetails.h"
Jointdetails::Jointdetails(void)
{
check = false ;
}
Jointdetails::~Jointdetails(void)
{
}
Jointdetails* Jointdetails::getInstance() {
static Jointdetails s_instance;
return &s_instance;
}
Analyzer.cpp
Analyzer::Analyzer(void)
{
m_ptheCTJointDetails = Jointdetails::getInstance();
}
0) you needn't use new so often.
1) you can construct your objects with the joint details as a parameter in your constructor.
To illustrate:
class Tst1 {
public:
Tst1(Jointdetails& pJointdetails) : analyzer1(pJointdetails) {
}
Analyzer analyzer1;
public:
~Tst1(void);
};
int RunProgram(Jointdetails& pJointdetails) {
Tst1(pJointdetails);
...
}
int main() {
Jointdetails jointdetails;
const int result(RunProgram(jointdetails));
return result;
}