I am using C language to upgrade my coding skills.
I designed a simple program because I wanted to easily find the problems what I looked for and arrange the works when I handle many problems as shown in below.
Here is my header file
#pragma once
#ifndef PROBLEM_H
#define PROBLEM_H
namespace PROBLEM_1 { int do_main(); }
typedef int(*MAINFUNC)();
#endif
And below is my source file.
#include "problems.h"
#include <stdio.h>
#include <iostream>
#include <string>
#include <algorithm>
#include <map>
using namespace std;
typedef int(*MAINFUNC)(void);
map<string, MAINFUNC> func_map;
void initialize_problem_map(void) {
func_map["problem_1"] = PROBLEM_1::do_main;
}
namespace PROBLEM_1 {
int do_main(void) {
cout << "hi" << endl;
return 1;
}
}
int main(void) {
string problem;
initialize_problem_map();
cin >> problem;
if (func_map.find(problem) != func_map.end())
return (*(func_map[problem]))();
return -1;
}
If I input "PROBLEM_1" then, the do_main functions in namespace PROBLEM_1 will be executed. I think that this design helps me organize multiple coding problems.
However, my question is about these two code lines as below.
if (func_map.find(problem) != func_map.end())
return (*(func_map[problem]))();
As you can see, the main fucntion's return type is "int". However, in the if-clause, i think that it return function-pointer. Therefore, I thought that those returning behavior is mismatched with the main function's return type. But, to my surprise, it worked well.
Could u explain this procedures regarding returning types?
func_map[problem], indeed, results in a function pointer. Applying the operator () on it, the function is invoked and the expression results in an int. Dereferencing a function pointer before its invocation is optional. This is symmetric with an optional address taking on a function name for initializing function pointers.
Indeed
func_map[problem]
is a pointer. However, you dereference the pointer with *:
*(func_map[problem])
and call function by adding ():
(*(func_map[problem]))()
which returns "int".
find returns an iterator; if this iterator is end, then the problem does not exist in the map; Because it is not end, it exists, then in the return line the pointer function obtained with [] is used to call it.
Related
I was looking through the source code of a project called CrossWindow-Graphics today when I saw an interesting function declaration. The code seemed to be declared as a function pointer. Here is a similar example I wrote.
#include <iostream>
using namespace std;
void (*Test())
{
cout << "Test Called!" << endl;
}
int main()
{
Test();
return 0;
}
My question is why does C++ allow this. I'd imagine it has something to do with function pointers. I remember that typedef is really just creating a variable and the name of the variable becomes the new type so I suppose this is just the same as creating a "variable" but it points to code. Even if that is the right idea, What is the purpose of that?
All you've really done here is add an extra pair of () that doesn't do anything.
We could write the same functin as
void* Test() { ... }
It's a function that returns a void*.
So the function should have a return statements where it returns a void pointer. Some compilers will warn about this as seen here.
I am having a problem with assigning new values to a dynamic int array that is a data member variable of the class IntersectionFlowRate(). I can initialize and print the values of the array inside the constructor. However, when I exit the constructor to the another class and then later call a function within the IntersectionFlowRate() class passing in variables to overwrite the initial values of the data member it will segmentation fault. I have debugged to find that overwriting the array is causing the seg fault. And that even attempting to access the dynamic array within one of its functions will seg fault.
My question is how can I edit the values of a dynamic int array member variable from within one of its functions i.e setArrayElement(int index, int x).
Here is some of my code. Sorry if I am unclear or missing something ridiculous. I have been stuck on this for hours.
#ifndef INTERSECTIONFLOWRATE_H
#define INTERSECTIONFLOWRATE_H
class IntersectionFlowRate
{
public:
IntersectionFlowRate();
~IntersectionFlowRate();
void setFlowCycle(int index, int flow);
private:
int* m_flowRateMotorCycle;
};
#endif
in the .h file ^
#include "IntersectionFlowRate.h"
#include <cstdlib>
#include <iostream>
#include <new>
using namespace std;
IntersectionFlowRate::IntersectionFlowRate()
{
const int SIZE = 4; //Constant for m_flowRates[] size
//DYNAMIC MEMORY DELETE LATER
m_flowRateMotorCycle = new int[SIZE];
for(int i = 0; i < SIZE; i++){
m_flowRateMotorCycle[i] = 0;
cout << m_flowRateMotorCycle[i] << endl;
cout << "WE GOT HERE" << endl;
}
}
void IntersectionFlowRate::setFlowCycle(int index, int flow){
cout << "INDEX: " << index << endl;
cout << "FLOW: " << flow << endl;
m_flowRateMotorCycle[index] = flow; //seg fault is here
}
I have another class that creates a pointer to a IntersectionFlowRate() object and then calls its setFlowCycle function passing in two VALID ints. With the debugging I was able pass 0 and 3 to the function setFlowCycle(0, 3) just fine and output those variables within the function.
#ifndef TRAFFICSIM_H
#define TRAFFICSIM_H
#include "IntersectionFlowRate.h"
using namespace std;
class TrafficSim
{
public:
TrafficSim(); //Default Constructor
TrafficSim(const char* file); //Constructor
~TrafficSim(); //Destructor
private:
IntersectionFlowRate* m_flowRate;
};
#endif
#include "TrafficSim.h"
#include "IntersectionFlowRate.h"
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
using namespace std;
TrafficSim::TrafficSim()
{
IntersectionFlowRate* m_flowRate = new IntersectionFlowRate();
m_flowRate->setFlowCycle(0, 3);
}
I replicated the error with this code. If no one else can I am completely unsure of what is possibly wrong anymore.
You are setting a local variable called m_flowRate, not the member variable m_flowRate of your TrafficSim class:
Instead of this:
TrafficSim::TrafficSim()
{
IntersectionFlowRate* m_flowRate = new IntersectionFlowRate();
m_flowRate->setFlowCycle(0, 3);
}
It should be this:
TrafficSim::TrafficSim()
{
m_flowRate = new IntersectionFlowRate();
m_flowRate->setFlowCycle(0, 3);
}
But overall, it not need be a pointer. It could be an object member within your class. That would cut down on the pointer usage a bit:
class TrafficSim
{
public:
TrafficSim(); //Default Constructor
TrafficSim(const char* file); //Constructor
private:
IntersectionFlowRate m_flowRate;
};
Then:
TrafficSim::TrafficSim()
{
m_flowRate.setFlowCycle(0, 3);
}
As to your question as to how to incorporate usage of std::vector in your class, here is a code sample of the IntersectionFlowRate class, rewritten using vector:
Vector sample
Also, another source of problems is that your classes fail to follow the Rule of 3 when you have pointers to dynamically allocated memory in your class.
Using std::vector takes care of this automatically, but if you insist on using pointers, you need to adhere to the directions at the link posted.
Yes, use a std::vector, it is much simpler, and it is a template so it also pretty fast and works any type (best for primitive types or pointers to objects) , and it also has boundary checking and other useful things.
If you need fast array-like access then you could use std::map which associates a key with a value, like so
std::map<UINT, YourClass*> m_mapIDs_to_YourClass;
When you first start using stl containers they might seem a little strange, but after a short while you cannot do without them, luckily they have been part of the C++ standard for some time now.
Boundary check for both these containers can be done by comparing your iterator to mapYourMap.end(), if they are equal you have passed the last element and trying to access data through the iterator will cause an exception.
Example for std::vector (if vecInt is a vector< int >):
vector<int>::iterator it = vecInt.begind();
if (it == vecInt.end()) return; // vector is empty
do { // runs through elememts until out of bound, useful for searching
i++
while (it != vecInt.end());
In c++11 standard we can declare variable in an unusual way. We can declare myVar as int(myVar); instead of int myVar. What is the point of this?
#include <iostream>
using namespace std;
int main() {
int(myVar);
myVar = 1000;
cout << myVar << endl;
return 0;
}
UPD Actually there is a certain reason why I asked this. What looked innocent just stopped to compile when we tried to port some code from MSVC C++03 to GCC C++11.
Here is an example
#include <iostream>
using namespace std;
struct MyAssert
{
MyAssert(bool)
{
}
};
#define ASSERT(cond) MyAssert(cond)
void func(void* ptr)
{
ASSERT(ptr); // error: declaration of ‘MyAssert ptr’
// shadows a parameter #define ASSERT(cond) MyAssert(cond)
}
int main()
{
func(nullptr);
return 0;
}
Sure. I can even do this:
int (main)()
{
}
Parentheses serve to group things in C and C++. They often do not carry additional meaning beyond grouping. Function calls/declarations/definitions are a bit special, but if you need convincing that we should not be allowed to omit them there, just look at Ruby, where parentheses are optional in function calls.
There is not necessarily a point to it. But sometimes being able to slap on some theoretically unnecessary parentheses helps make code easier to read. Not in your particular example, and not in mine, of course.
#include <typeinfo>
#include <iostream>
int main(void)
{
int *first_var[2];
int (*second_var)[2];
std::cout << typeid(first_var).name() << std::endl;
std::cout << typeid(second_var).name() << std::endl;
return 0;
}
Running this on my machine gives :
A2_Pi
PA2_i
The parenthesis in the declaration mostly serve the same purpose they do everywhere, group things that should be together regardless of the default priority order of the language.
Of course parenthesis with only one element inside is equivalent to just typing that element except in cases where parenthesis are mandatory (e.g function calls).
C++ does not break backward compatibility if it can help it.
The C that it was developed from had this syntax. So C++ inherited it.
A side effect of this backward compatibility are the vexing parse problems. They have not proved sufficiently vexing to justify breaking backward compatibility.
I'm building custom operators and im having problems when passing parameters to them.
For example
class test{
public:
test operator[](vector <string> s){
test a;
return a;
}
};
Now if I wanted in my main program to do something like this
int main(){
test d;
vector<string> s;
s.push_back("bla");
d[s];
}
I get a bunch of errors. Is it because I need to have const somewhere or I don't know.
Also I have built in a custom operator for printing out the class test ( << operator ). Now I don't get compile error when calling d[s] in main program but I get compile error when calling cout<< d[s] in main program. The operator << is working because I tested it with simple cout<< d
return test;
test is a type. You can't return a type. Perhaps you meant:
return a;
But then you have another problem because you're returning a reference to a local variable. The object a will be destroyed when the function returns (because that is its scope) and so the reference will be left dangling.
Code working fine using gcc compiler.
#include <string>
#include <vector>
using namespace std;
class test{
public:
test operator[](vector <string> s){
test a;
return a;
}
};
int main(){
test d;
vector<string> s;
s.push_back("bla");
d[s];
}
Notwithstanding the errors that other folk have already pointed out (dangling reference, returning a type rather than the value), note that if you intend to override [], you should also consider overriding the pointer deference operator (unary *) too as many folk use them interchangeably.
In my class.h i got:
template<class T> void Swap(T, T);
And in class.cpp:
template<class T>
void class::Swap(T& p1, T& p2)
{
T aux = p1;
p1 = p2;
p2 = aux;
}
When I try :
this->Swap<char*>(&lit[i][k], &lit[i][l]);
And another question:
What am i doing wrong here: i want to split my string after some delimitators ("+-") and strtok isn't working as I expected.
int counter = 0;
char* s = strtok(eq_clone ," ");
while(s != NULL)
{
counter++;
if(s == "")
counter--;
s = strtok(eq_clone ,"+-");
}
This looks like a mistake as it will never be true:
if(s == "")
this is comparing the address of s to the address of the string literal "": it is not checking if s is an empty string. An alternative to using strtok() would be boost::algorithm::split:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
int main()
{
std::string s("a,string+with-multiple delimiters");
std::vector<std::string> s_tokens;
boost::algorithm::split(s_tokens, s, boost::is_any_of(",+- "));
std::for_each(s_tokens.begin(),
s_tokens.end(),
[] (const std::string& s)
{
std::cout << s << "\n";
});
return 0;
}
Output:
a
string
with
multiple
delimiters
Regarding swap, as has already been stated in comments and other answer(s) just use std::swap(). I am guessing that lit is a char[][] so std::swap(lit[i][k], lit[i][l]); will do exactly what you require.
EDIT:
After comment giving declaration string* lit and that lit appears to be an array (from example usage) then use std::swap() in this manner:
std::string* lit = new std::string[4];
lit[0] = "zero";
std::swap(lit[0][1], lit[0][2]); // The characters will be passed by reference,
// don't take address.
std::cout << lit[0] << "\n"; // Prints "zreo"
Note, that the declaration of your Swap() passes arguments by value (incorrect), but the definition of Swap() passes arguments by reference (correct). If you change the declaration of your Swap() and invoke it as follows it will work (if you really don't want to use std::swap():
template<class T> void Swap(T&, T&);
//^ //^
Swap(lit[i][k], lit[i][l]);
1) Why is Swap() a class member? Class members should somehow be tightly coupled to your classes. In most cases it is is sign of bad design if something, which does not use private members or is very similar to a method that does (i.e. a convinience method), becomes a class member. C++ is not java where everything has to belong to a class. Make your swap() method a free standing template method.
2) Better yet, do not reinvent the wheel. std::swap() is there and it works mightily well. In many cases you can expect the methods and classes provided by the standard library to work better than something you could write up.
3) In your class you called the method Sort(), but the question is about Swap(). Since you did not write what you expected to happen and what actually happens, this is the only thing I can find which might be wrong.
4) Do not use strtok() in C++ unless you have to. char* are C-Style strings and should not be used in C++. Use std::string instead.