I have one application in which following task are to be done
1.) UI application will send command code (integer value).
2.) DLL interface(in c++) will get that integer value and execute corresponding command function.
commands name and command code are maintained as
#define PING 50
there will be 500 commands and applying SWITCH CASE will not sound good. so i decided to implement function pointer in my code as below
#include "stdafx.h"
#include<iostream>
#define PING 20
using namespace std;
//extern const int PING = 10;
void ping()
{
cout<<"ping command executed";
}
void get_status(void)
{
cout<<"Get_status called"<<endl;
}
class ToDoCommands
{
public:
void getCommand( void (*CommandToCall)() );
};
void ToDoCommands::getCommand( void (*CommandToCall)())
{
void (*CommandToCall1)();
CommandToCall1 = CommandToCall;
CommandToCall1();
}
int main()
{
int code;
ToDoCommands obj;
cout<<"enter command code";
cin>>code; // if UI send 50 then Ping function get executed as #define PING 50
obj.getCommand(ping); // here m passing ping manually..
//obj.getCommand(get_status);
return 0;
}
how can i pass command name corresponding to command code in
obj.getCommand(ping);
You are almost there: make a std::map of std::string to function pointer, initialize it with data pairing a string name to a corresponding function pointer, and then use that map at runtime to pick the correct pointer based on the string parameter passed in.
#include <iostream>
#include <string>
#include <map>
using namespace std;
void ping() {
cout << "ping" << endl;
}
void test() {
cout << "test" << endl;
}
int main() {
map<string,void(*)()> m;
m["ping"] = ping;
m["test"] = test;
// I am using hard-coded constants below.
// In your case, strings will come from command line args
m["test"]();
m["ping"]();
return 0;
}
Link to a demo with std::map.
Here is how you can do it without a map (it will be slower because of the linear search, but you can fix it by ordering names alphabetically and using binary search).
#include <iostream>
#include <cstring>
using namespace std;
void ping() {
cout << "ping" << endl;
}
void test() {
cout << "test" << endl;
}
typedef void (*fptr_t)();
int main() {
const fptr_t fptrs[] = {test, ping};
const char *names[] = {"test", "ping"};
const char *fname = "test";
for (int i = 0 ; i != 2 ; i++) {
if (!strcmp(fname, names[i])) {
fptrs[i]();
break;
}
}
return 0;
}
Link to a demo with arrays.
Declare an array of function pointers. Where you treat the index as your "code". For example:
void foo(){
printf("foo\n");
}
void bar(){
printf("bar\n");
}
int main(void)
{
void (*code_to_function[100])();
int code;
code_to_function[0] = foo;
code_to_function[1] = bar;
printf("Enter code: ");
scanf("%d", &code);
code_to_function[code]();
return 0;
}
Please note that for this rudimentary example, inputting integer code other than 0 and 1 will result in a segfault.
I should say #dasblinkenlight is right but if you don't want to use std::map you should implement a map yourself. This can be buggy and not a optimized way, but if you don't want to use STL, it seems you should implement it yourself.
You can use 2 arrays with corresponding indices. One of them is a char * array and another one is function pointers. They are better to be encapsulated in a class named something like MyMap.
class MyMap {
public:
...
inline void add(char *name, (void (*ptr)(void)) ) {
names_[currIndex_] = name; // Or stcpy
ptrs_[currIndex_] = ptr;
currIndex_++;
}
inline (void(*)(void)) get(char *name) {
int foundIndex = -1;
for (int i = 0; i < currIndex_; i++) {
// Find matching index
}
if (foundIndex_ >= 0) {
return ptrs_[foundIndex_];
}
return NULL;
}
private:
int currIndex_;
char *names_[10];
(void (*ptrs_[10])(void));
};
Related
This has been driving me insane for hours - I'm new to C++: I can't figure out why my programs thinks I want it do this.
I have a class House
class House{
private:
int number;
std::string family;
public:
House(int n, std::string f){
this->number = n;
this->family = f;
}
House(){
this->number = 0;
this->family = "unassigned";
}
void whoLivesHere(){
std::cout<<"The"<<family<<"lives here."<<std::endl;
}
};
I have another class Neighborhood
class Neighborhood{
private:
int size;
House houses[100];
public:
Neighborhood(){
this->size=0;
}
void addHouse(House h){
this->houses[this->size] = h;
this->size++;
}
void whoLivesHere(){
for(int i=0; i<this->size; i++){
this->houses[this->size].whoLivesHere();
}
}
};
And this is what is happening on my main.
int main(){
Neighborhood n1;
House h1(1,"Johnsons");
House h2(1,"Jones");
n1.addHouse(h1);
n1.addHouse(h2);
n1.whoLivesHere();
return 0;
}
And what I get on the Terminal is this.
The unassigned lives here
The unassigned lives here
The unassigned lives here
Why didn't the new objects replace the first two default objects?
Why show three objects? If size should be 1.
Thank you tonnes in advance!
You can make short work of this problem by using the tools the C++ Standard Library gives you, like this:
#include <string>
#include <vector>
#include <iostream>
int main() {
std::vector<House> neighborhood;
// emplace_back() forwards arguments to the constructor
neighborhood.emplace_back(1, "Johnson");
neighborhood.emplace_back(2, "Jones");
// No need to track size, std::vector does that for you: size(),
// but that's not even needed to iterate, you can just do this:
for (auto& house : neighborhood) {
house.whoLivesHere();
}
return 0;
}
Here I've cleaned up your House implementation:
class House {
private:
int number;
std::string family;
public:
// Tip: Use constructor lists
House(int n, const std::string& f) : number(n), family(f) { };
// Useful even for defaults
House() : number(0), family("unassigned") { };
// Flag methods that don't modify anything as const
void whoLivesHere() const {
std::cout << "The " << family << " lives here at number " << number << "." << std::endl;
}
};
I created a class that represents a packet of information as described on this code:
#ifndef PACKET_H_
#define PACKET_H_
namespace std {
class Packet
{
public:
Packet();
virtual ~Packet();
void initClass();
void setStartP(char);
void setAddFrom(char);
void setAddTo(char);
void setpDataSize(char);
void setpNumber(char);
void setChecksum(char);
void setEndP(char);
void LoadData(char);
char getStartP();
char getAddFrom();
char getAddTo();
char getpDataSize();
char getChecksum();
char getEndP();
char getData();
private:
char pB[261];
char pDataMax;
char pDataIndex;
};
} /* namespace std */
#endif /* PACKET_H_ */
#include "Packet.h"
#include <iostream>
namespace std {
Packet::Packet()
{
pDataIndex = 0;
initClass();
}
Packet::~Packet()
{
delete this;
}
void Packet::setStartP(char startChar)
{
pB[0] = startChar;
cout << "in Set!";
}
void Packet::setAddFrom(char fromChar)
{
}
void Packet::setAddTo(char toChar)
{
}
void Packet::setpDataSize(char dataSizeChar)
{
}
void Packet::setpNumber(char packetNumber)
{
}
void Packet::setChecksum(char checksumChar)
{
}
void Packet::setEndP(char endChar)
{
}
void Packet::LoadData(char dataChar)
{
}
char Packet::getStartP()
{
return pB[0];
cout << "in Get";
}
char Packet::getAddFrom()
{
return pB[1];
}
char Packet::getAddTo()
{
return pB[2];
}
char Packet::getpDataSize()
{
return pB[3];
}
char Packet::getChecksum()
{
return pB[4];
}
char Packet::getEndP()
{
return pB[260];
}
char Packet::getData()
{
return pB[6 + pDataIndex];
}
void Packet::initClass()
{
pDataMax = 254;
pDataIndex = 0;
}
}
At this point i am just testing it so I just implemented two of the methods. When I try to run the program:
#include <iostream>
#include "Packet.h"
using namespace std;
Packet myPacket;
void buildPacket();
int main() {
buildPacket();
return 0;
}
void buildPacket( )
{
char startP = 0x28;
cout << "Setting startP!" << endl;
myPacket.setStartP(startP);
cout << "Getting startP" << endl;
cout << myPacket.getStartP() << endl;
cout << "Done";
}
The code is fine a compile/build time no issues there, it is a run time it falls over. This is really thruowing me, it really is making me doubt what I actually know about class creation and use in C++.
The program will run up to a certain point and then crashes with a windows message. on the console this is as far as it gets before crashing:
Setting startP!
in Set!Getting startP
(
As I can see it it seems to be on deletion that it crashes but not sure why. I looked around for similar issues but can't really find a reason why it is coming up with this, I would be grateful for some help on this one.
Don't call delete this in the destructor. The object is automatically destructed since it goes out of scope, no need for delete.
You can read more about it here: http://en.cppreference.com/w/cpp/language/scope
I've been recently working on a program which consists basically of 24 variations of one function(below). Everything gets executed perfectly apart from the part where I try to compare functions(with eachother). I found out that it is possible to be done by writing 24 if-else statements, yet I am certain there is a shorter way. I've also tried with vectors but no luck for now. Thanks for any help!
one of 24 functions:
int funk1()
{
ifstream myfile ("file.txt");
string line;
int i;
class1 obj1;
obj1.atr1= "Somename";
obj1.atr2="GAATTC";
while (getline(myfile, line))
{
i = countSubstring(line, obj1.atr2);
obj1.sum += i;
};
cout<<obj1.sum<<": "<<obj1.atr1<<"\n";
return obj1.sum;
}
The main function:
int main(){
funk1();
funk2();
funk3();
funk4();
funk5();
funk6();
funk7();
funk8();
funk9();
funk10();
funk11();
funk12();
funk13();
funk14();
funk15();
funk16();
funk17();
funk18();
funk19();
funk20();
funk21();
funk22();
funk23();
funk24();
//This is one way to do it
if (funk18() > funk1())
{
cout<<funk18<<" is the biggest";
}
//...
}
Here is a clean and elegant c++11 solution:
#include <iostream>
#include <functional>
#include <vector>
#include <limits>
#include <algorithm>
using namespace std;
using MyFunc = std::function<int()>;
int f1() { return 1; }
int f2() { return 15;}
int f3() { return 3; }
int main() {
std::vector<MyFunc> my_functions = {f1, f2, f3};
int max = std::numeric_limits<int>::min();
for (auto const &f : my_functions) {
max = std::max(max, f());
}
cout << max << endl;
return 0;
}
if you want to store the results from functions instead, you could do:
std::vector<int> my_results;
my_results.reserve(my_functions.size());
for (auto const &f : my_functions) {
my_results.push_back(f());
}
auto max_it = std::max_element(std::begin(my_results), std::end(my_results));
cout << *max_it << endl;
When I try debugging the code, it runs into the debugging error "c++ Expression: string subscript out of range"
Pretty sure the problem was brought while calling setCode().
How do I fix the code inside setCode()?
#include <iostream>
#include <stdlib.h>
#include <string>
#include <fstream>
#include <list>
using namespace std;
class test
{
private:
string code;
int digit;
public:
//constructor
test(): code(""), digit(0) { }
//copy constructor
test(const test &other):
digit(other.digit)
{
for(unsigned int i=0; i < code.length(); i++)
code[digit] = other.code[digit];
}
//set up the private values
void setCode(const string &temp, const int num);
void setDigit(const int &num);
//return the value of the pointer character
const string &getCode() const;
const unsigned int getDigit() const;
};
const string& test::getCode() const
{
return code;
}
const unsigned int test::getDigit() const
{
return digit;
}
void test::setCode(const string &temp, int num)
{
code[num] = temp[num];
}
void test::setDigit(const int &num)
{
digit = num;
}
int main()
{
string contents = "dfskr-123";
test aisbn;
list<test> simul;
list<test>::iterator testitr;
testitr = simul.begin();
int count = 0;
cout << contents << '\n';
aisbn.setCode(contents, count);
aisbn.setDigit(count);
simul.push_back(aisbn);
count++;
/*for(; testitr !=simul.end(); simul++)
{
cout << testitr->getCode() << "\n";
}*/
}
When you create an instance of the test class, the string inside it is empty. This means that whenever you do e.g. code[something] you will be out of range. It doesn't matter what the index is.
You either need to set the string to a certain length from the start, and make sure that the index is within the range. Or to make sure that the index is within range by dynamically extending the string when needed.
You have to make sure that when this statement executes:
code[num] = temp[num];
both code and temp are at least of size num + 1.
I have a class for performing various array operations. I like to use my insert method in my populate method.
Can someone guide me on that? Here is the code:
#include <iostream>
#include <cstdlib>
using namespace std;
const int MAX=5;
class array
{
private:
int arr[MAX];
public:
void insert(int pos, int num);
void populate(int[]);
void del(int pos);
void reverse();
void display();
void search(int num);
};
void array::populate(int a[])
{
for (int i=0;i<MAX;i++)
{
arr[i]=a[i];
}
}
void array::insert(int pos, int num)
{
for (int i=MAX-1;i>=pos;i--)
{
arr[i] = arr[i-1];
arr[i]=num;
}
}
void array::del(int pos)
{
for (int i=pos;i<MAX;i++)
{
arr[pos]=arr[pos + 1];
}
}
void array::display()
{
for (int i=0;i<MAX;i++)
cout<<arr[i];
}
void array::search(int num)
{
for (int i=0;i<MAX;i++)
{
if (arr[i]==num)
{
cout<<"\n"<<num<<" found at index "<<i;
break;
}
if (i==MAX)
{
cout<<num <<" does not exist!";
}
}
}
int main()
{
array a;
for (int j=0;j<MAX;j++)
{
a.insert(j,j);
}
a.populate(a);
a.insert(2,7);
a.display();
a.search(44);
system("pause");
}
I like to use my insert method in my
populate method. Can someone guide me
on that?
That would mean that instead of the straightforward and efficient "copy from one array to another" approach, you'd call insert for each value of the input with the correct index in place of the assignment.
To call a method on the current instance, from inside a method:
insert(x, y);
//or
this->insert(x, y);
Your code also contains an error, in that you pass a wrong type to populate in main. It expect int* (a real array), not an array object.
Please elaborate your question. If you just need a good container have a look at the STL (Standard Template Library) std::vector. It's part of the C++ standard and comes with your compiler.
If you want to learn how to write a custom class, please try to be more precise in your question.
Also consider the wealth of beginner tutorials available on the net, for example:
http://www.learncpp.com/
Here is a little example on how to write a custom class with one member function calling the other and accessing a private data member (note that inside a member function you can refer to any other member directly):
#include <iostream>
class Example
{
private:
int some_private_stuff;
public:
Example();
void function_a();
void function_b();
};
Example::Example(){
some_private_stuff = 1;
}
void Example::function_a(){
std::cout << "this is function a" << std::endl;
some_private_stuff = 2;
std::cout << "changed private_stuff to " << some_private_stuff << std::endl;
}
void Example::function_b(){
std::cout << "this is function b" << std::endl;
function_a();
}
int main() {
Example e;
e.function_b();
return 0;
}