I have:
Command *command;
if(commandType == "Start")
{
command = new StartCommand();
}
else if (commandType == "Stop")
{
command = new StopCommand();
}
Now suppose I want command to be a shared_ptr, how do I translate the code above to use a shared_ptr?
Skipping the obvious, if you want to properly initialise your variable, e.g. if it's const, you could do it like this
std::shared_ptr<Command> factoryCommand(std::string const& commandType) {
if(commandType == "Start")
return std::make_shared<StartCommand>();
if(commandType == "Stop")
return std::make_shared<StopCommand>();
return std::shared_ptr<Command>(nullptr);
}
std::shared_ptr<Command> const command {factoryCommand(commandType)};
As indicated in the comments, you can also violate the RAII guideline of C++ and separate definition and initialisation. I would still prefer to use std::shared_ptr<Command>::operator= over std::shared_ptr<Command>::reset though, as it is more intuitive and doesn't trick you into newing something you will never delete.
So, for the "Start" branch, for example, this would look like this:
std::shared_ptr<Command> command;
//...
// I would flag this in the review process as "you're doing it wrong"
command.reset(new StartCommand());
// This is what you should do if you *have* to separate definition and initialisation:
command = std::make_shared<StartCommand>();
Some very simple changes will do the job:
shared_ptr<Command> command;
if(commandType == "Start")
{
command = make_shared<StartCommand>();
}
else if (commandType == "Stop")
{
command = make_shared<StopCommand>();
}
Related
I am using getopt to parse command line arguments and my issue is that some of my options have options. My project is to test different backend implementations of maps and the -b flag specifies which implementation to use. Most of the options are straight forward but for the backends that use hash tables (chained and open) there is an additional -number that can be added to the end to specify the load factor. So it would be -b chained-0.75.
My idea is that I would take the substring from 8 to the end (or 5 for the "open" option) because that would ignore the "chained-" part of the string and then use atof() to convert it to a double and then declare my map. I believe optarg is a char array (?) and I keep running into type mismatch errors even though I have tried std::string str(optarg); I also don't know what to write in place of else if (strcasecmp(optarg, "chained") == 0) because there could be any number at the end of it. So right now when I do -b chained-0.75 it calls the usage function.
Here is what I have so far:
while ((c = getopt(argc, argv, "hb:n:p:")) != -1) {
switch (c) {
case 'b':
if (strcasecmp(optarg, "unsorted") == 0) {
map = new UnsortedMap();
} else if (strcasecmp(optarg, "sorted") == 0) {
map = new SortedMap();
} else if (strcasecmp(optarg, "bst") == 0) {
map = new BSTMap();
} else if (strcasecmp(optarg, "unordered") == 0) {
map = new UnorderedMap();
} else if (strcasecmp(optarg, "chained") == 0) {
double load_factor;
std::string str(optarg);
std::string ld_str = str.substr(8, str.length()-1);
load_factor = atof(ld_str);
map = new ChainedMap(load_factor);
} else if (strcasecmp(optarg, "open") == 0) {
map = new OpenMap();
} else {
usage(1);
}
break;
Any hints or ideas would be appreciated!
strcasecmp() is an exact match comparison function, this strcasecmp() will obviously not match "chained-0.75". The only thing that strcasecmp() will match against the string "chained" is "chained", not "chained-0.75", not "changed-foobar", not "chained-anything".
The right function is strncasecmp:
} else if (strncasecmp(optarg, "chained-", 8) == 0) {
Note that you're comparing against "chained-", and not just "chained". A few moments' of thinking should make it clear why.
The existing code also fails to take into account the possibility that the string after "chained-" is not a number, since atof() does not handle parsing errors. If you need to be able to detect and handle an error here, use strtod() instead of atof().
I'm trying to implement a very basic clone of redis in C++. So when I get the queries, I need to parse those. Right now I am doing this:
void Query::buildQuery(){
std::string query_type = lower(args[0]);
if(query_type == "get"){ //do something }
else if(query_type == "set"){ //do something }
else if(query_type == "getbit"){ //do something }
else if(query_type == "setbit"){ //do something }
else if(query_type == "zadd"){ //do something }
else if(query_type == "zcard"){ //do something }
else if(query_type == "zcount"){ //do something }
else if(query_type == "zrange"){ //do something }
else if(query_type == "save"){ //do something }
else { throw(QueryException("Invalid query type")); }
}
Is there any other, shorter way to do this? I don't want to include any other library than the STL.
If those do_somethings can be extracted into separate methods, then you could create a pre-initialized hash map (unordered_map) from string to pointer to member function and do something like
(this->*queryHandlers[query_type])();
You'll have to choose between lots of functions and one large function, though.
If you're running on an Intel/AMD processor and feeling 'brave' you might like to take a look at these implementations of strcmp, strlen, etc that use SSE instructions. That'd be quicker.
As for the general structure, you could turn "set" & "do something" into an class which has a test method and a do-something method. Have an array of those, and iterate across it calling the test method passing query_type. The test method for the object would automatically call the do-something method if it matches the string.
Without if...else if, you can do this by switch statement. Like:
void Query::buildQuery(){
std::string query_type = lower(args[0]);
switch(str2int(query_type) ){
case str2int("set"):// do something
break;
case str2int("getbit"):// do something
break;
................
..........
default:
throw(QueryException("Invalid query type"));
}
}
According to Serhiy where str2int is like:
constexpr unsigned int str2int(const char* str, int h = 0)
{
return !str[h] ? 5381 : (str2int(str, h+1)*33) ^ str[h];
}
For my assignment, I'm storing user login infos. I'm taking in a string which is the command. The command can be create, login, remove, etc. There are 10 total options, i.e 10 different strings possible. Can anyone explain a more efficient way to write this instead of 10 if and else if statements? Basically how should I format/structure things besides using a bunch of if (string == "one"), else if (string == "two"). Thank you
I expect that your lecturer would like you to extract function to another re-usable function:
string action;
command = CreateAction(action);
command.Do(...);
Ofcourse, inside you CreateAction class you still need to have the conditionals that determine which commands need to be created.
AbstractCommand CreateAction(action)
{
if (action == "login")
return LoginCommand();
else if (action == "remove")
return RemoveCommand();
..... etc etc
}
And if you really want to get rid of all the conditionals than you can create some self-registering commands but that involves a lot more code and classes......
You should look up things like Command Pattern and Factory Pattern
You can use function pointers and a lookup table.
typedef void (*Function_Pointer)(void);
void Create(void);
void Login(void);
void Remove(void);
struct Function_Option_Entry
{
const char * option_text;
Function_Pointer p_function;
};
Function_Option_Entry option_table[] =
{
{"one", Create},
{"two", Login},
{"three", Remove},
};
const unsigned int option_table_size =
sizeof(option_table) / sizeof(option_table[0]);
//...
std::string option_text;
//...
for (i = 0; i < option_table_size; ++i)
{
if (option_text == option_table[i].option_text)
{
option_table[i].p_function();
break;
}
}
Use a switch, and a simple hash-function.
You need to use a hash-function, because C and C++ only allow switching on integral values.
template<size_t N> constexpr char myhash(const char &x[N]) { return x[0] ^ (x[1]+63); }
char myhash(const string& x) { return x.size() ? x[0] ^ (x[1]+63) : 0; }
switch(myhash(s)) {
case myhash("one"):
if(s != "one") goto nomatch;
// do things
break;
case myhash("two"):
if(s != "two") goto nomatch;
// do things
break;
default:
nomatch:
// No match
}
Slight adjustments are needed if you are not using std::string.
I would recommend you to create a function for every specific string. For example, if you receive a string "create" you will call function doCreate(), if you receive a string "login" then you call function doLogin()
The only restriction on these function is that all of them must have the same signature. In an example above it was smh like this:
typedef void (*func_t) ();
The idea is to create a std::map from strings to these functions. So you wouldn't have to write 10 if's or so because you will be able to simple choose the right function from the map by the name of a specific string name. Let me explain it by the means of a small example:
typedef void (*func_t) ();
void doCreate()
{
std::cout << "Create function called!\n";
}
void doLogin()
{
std::cout << "Login function called!\n";
}
std::map<std::string, func_t> functionMap;
void initMap()
{
functionMap["create"] = doCreate;
functionMap["login"] = doLogin;
}
int main()
{
initMap();
std::string str = "login";
functionMap[str](); // will call doLogin()
str = "create";
functionMap[str](); // will call doCreate()
std::string userStr;
// let's now assume that we also can receive a string not from our set of functions
std::cin >> userStr;
if (functionMap.count(userStr))
{
functionMap[str](); // now we call doCreate() or doLogin()
}
else
{
std::cout << "Unknown command\n";
}
return 0;
}
I hope it will help you in someway=)
You can use a map which does the comparison for you.
Something like this:
Initialise map:
std::map<std::string, std::function<void(std::string&)>> map;
map["login"] = std::bind(&Class::DoLogin, this, std::placeholders::_1);
map["create"] = std::bind(&Class::DoCreate, this, std::placeholders::_1);
Receive message:
map.at(rx.msg_type)(rx.msg_data);
Handler:
void Class::DoLogin(const std::string& data)
{
// do login
}
Maybe you can create a std::map<std::string, int> and use map lookups to get the code of the command that was passed - you can later switch on that number. Or create an enum Command and have a std::map<std::string, Command> and use the switch.
Example:
enum Command
{
CREATE,
LOGIN,
...
};
std::map<std::string, Command> commandNameToCode;
// fill the map with appropriate values
commandNameToCode["create"] = Command::CREATE;
// somehow get command name from user and store in the below variable (not shown)
std::string input;
// check if the command is in the map and if so, act accordingly
if(commandNameToCode.find(input) != commandNameToCode.end())
{
switch(commandNameToCode[input])
{
case CREATE:
// handle create
break;
...
}
}
I've come across a situation where I have a bunch of "systems" that need to be initialized in sequence, with the next system only being initialized if all of the proceeding systems initialized successfully.
This has led me to a whole slew of nested if - else statements. Here's some pseudo-code for visualization.
bool mainInit () {
if (!system1Init ()) {
reportError (); // some error reporting function
}
else {
if (!system2Init ()) {
reportError ();
}
else {
if (!system3Init ()) {
// ... and so on
I find that this starts to look like a mess when you get even a handful of levels to it.
Now I thought of using a switch statement instead, starting at the first case and falling through to the other cases on success, only breaking if there's an error.
bool mainInit () {
switch (1) {
case 1:
if (!system1Init ()) {
reportError ();
break;
}
case 2:
if (!system2Init ())
reportError ();
break;
}
// ....
}
Now, I like this a lot better. I find it much easier to read, especially with some decent comments, but I'm fairly new to programming.
So, my question is: Seeing how this is not how switch statements are traditionally used(at least from what I've seen), is something like this acceptable, or would this be considered bad form?
Being new to programming, I'm trying not to develop too many bad habits that might frustrate and make things more difficult for other programmers down the road.
I did a search, but most of what I found had to do with replacing chains of if - else if statements, not replacing nested ones.
Reference all of the systems in an array, for example an std::vector<mySystem*>, and loop over them sequentially, breaking off on the first fail. This way your entire code is reduced to less than 5 lines of code, even for 500+ systems.
The suggested switch hack is an evil example of XY problem solving: your real problem is that you don't have the array of systems, and are using named variables, thus eliminating all options to more flexibly use all systems, like in a loop.
Assuming that all your system#Init() calls are known at compile time, you can very easily put them in a table and then iterate over that table.
typedef (*system_init)(void);
system_init initialization_functions[] =
{
system1Init,
system2Init,
system3Init,
...
systemNInit
};
bool mainInit()
{
for(size_t idx(0); idx < sizeof(initialization_functions) / sizeof(initialization_functions[0]); ++idx)
{
if(!initialization_functions[idx]())
{
ReportError();
return false;
}
}
return true;
}
However, your existing code looks incorrect since the first mainInit() only calls system1Init() and then exits. Probably not what you wanted in the first place.
if(!system1Init())
{
ReportError();
return false;
}
// if you add an else, the system2Init() does not get called
// even if system1Init() succeeds
if(!system2Init())
{
ReportError();
return false;
}
[...]
return true;
Would the switch answer your problem? Not as it was written. That is, if you wanted to call the mainInit() function with a counter, it could be useful. Drupal uses that mechanism:
bool mainInit(int idx)
{
bool r(true);
switch(idx)
{
case 1:
r = system1Init();
break;
case 2:
r = system2Init();
break;
[...]
}
if(!r)
{
ReportError();
}
return r
}
Note that the table mechanism works the same way as the switch. As long as all the code is found in the systemNInit() functions (and it should be), the switch does not add anything, so you could do something like this too:
bool mainInit(int idx)
{
if(idx < 0 || idx >= sizeof(initialization_functions) / sizeof(initialization_functions[0]))
{
throw std::range_error("index out of bounds");
}
if(!initialization_functions[idx]())
{
ReportError();
return false;
}
return true;
}
Calling the mainInit() with an index can be helpful in case you want to "de-initialize" properly:
int main()
{
for(size_t idx(0); idx < ...; ++idx)
{
if(!mainInit(idx))
{
while(idx > 0)
{
--idx;
mainDeinit(idx);
}
exit(1);
}
}
...app do something here...
}
Use custom exceptions with clear error messages and add a try-catch-report-die around the code in main(). Exceptions are there to specifically make your case look good by making "bad path" implicit.
void initX() { ...; throw std::invalid_argument_exception("..."); }
int main() {
try {
init1(); init2(); ... run();
return 0;
} catch (std::exception const& e) {
log(e.what()); exit 42;
}
}
I'd do it this way:
bool mainInit () {
if (!system1Init ()) {
return(false);
}
if (!system2Init ()) {
return(false);
}
if (!system3Init ()) {
return(false);
}
//...
return(true);
}
//...
if(!mainInit()) {
reportError();
}
Suppose multiple comparations are required at once:
enum usermode
{
active,
standingby,
inactive,
dead,
// many other modes....
};
class A
{
public:
usermode mode;
};
function inherited pointer to class A (ptr points to A)
Method A:
if( ptr->mode == active || ptr->mode == standingby || ptr->mode == inactive || ptr->mode == dead ...//etc )
{
//do something
}
Method B:
usermode cmpmode = ptr->mode;
if( cmpmode == active || cmpmode == standingby || cmpmode == inactive || cmpmode == dead ...//etc )
{
//do something
}
Is it a good practice to do so?
In this case it simply cuts down on the amount of characters in the if statement expression, so whatever works and is most readable.
However, in the case of checking the return value of a function, I would stuff it into a variable and check that, i.e.,
auto ret = SomePossiblyExpensiveOperation();
if(ret != whatever && ret < something) {
//...
}
Taking your if statement at face value, I would do this:
switch(ptr->mode) {
case active:
case standingby:
case inactive:
case dead:
ptr->whatever();
break;
// other cases
default:
// something else
break:
}
If this is a common check, you may want to make a special case for it, i.e.,
usermode any_mode = active | standingby | inactive | dead;
//...
if(ptr->mode & any_mode) {
// whatever...
}
Since mode is just a member variable of the class, any decent compiler will generate the same code for both implementations. However, in general, these two approaches are not equivalent if you would use methods instead of fields (especially methods with side effects).
This is covered in more details at Function calls vs. local variables
It would probably be nicer if your class has a method to handle this directly
bool A::IsSomeState() const
{
return mode == active || mode == standingby; // Etc
}