When I cout my lettercase variable to the console, I get -858993460. Everything else seems to be working okay. What am I missing here?
So here's a sample of my code:
Here's main:
int main()
{
int lettercase = 0;
Switch switcher(lettercase);
lettercase = switcher.getLettercase();
cout << "Lettercase: " << lettercase << endl;
return 0;
}
I also have a separate class called Switch.
Here's a sample of its header file:
class Switch {
public:
// DEFAULT CONSTRUCTOR
Switch();
// OVERLOAD CONSTRUCTOR
Switch(int);
// DESTRUCTOR
~Switch();
// Lettercase accessor
int getLettercase();
private:
int lettercase;
};
And here's a sample of my definition:
// DEFAULT
Switch::Switch() {
int lettercase = 0;
}
// OVERLOAD
Switch::Switch(int lettercase) {
// CHANGE LETTER CASE
if (lettercase == 1) {
lettercase = 0;
} else {
lettercase = 1;
}
}
// DESTRUCTOR
Switch::~Switch() {
}
// ACCESSOR
int Switch::getLettercase() {
return lettercase;
}
// OVERLOAD
Switch::Switch(int lettercase) {
// CHANGE LETTER CASE
if (lettercase == 1) {
lettercase = 0;
} else {
lettercase = 1;
}
}
You have scope issues here. You're trying to change the class variable lettercase, but because the argument for the constructor is also called lettercase, you have to use this->lettercase if you want to access the class variable. I suggest changing the name of your parameter here.
Something like this:
// OVERLOAD
Switch::Switch(int initCase) {
// CHANGE LETTER CASE
if (initCase == 1) {
lettercase = 0;
} else {
lettercase = 1;
}
}
The reason you were getting that odd int is because your scope issues prevented you from ever initializing the class variable lettercase, but your getter was still accessing this variable and returning the uninitialized value.
EDIT: Your default constructor also has a problem, here:
Switch::Switch() {
int lettercase = 0;
}
This isn't doing what you think it's doing (or what you want it to do). Rather than initializing the class variable, lettercase, this is creating a new variable, lettercase, (scope) and initializes it to 0. Instead, your default constructor should look like this:
Switch::Switch() {
lettercase = 0;
}
Related
I want to use different functions depending on the input to calculate the output.
but it says: (expression preceding parentheses of apparent call must have (pointer-to-) function type)
int (TestClass::* Gate_Func)(vector); <<== this is the function I initiated.
and then here: Gate_Func = &TestClass::AND;
I can reference to the AND function with Gate_Func
but why
output = Gate_Func(InputArr);
this one has an error:
C++ expression preceding parentheses of apparent call must have (pointer-to-) function type
#include <iostream>
#include <vector>
using namespace std;
class TestClass {
public:
int AND(vector<int> inputarr) {
return (inputarr[0] == 1 && inputarr[1] == 1);
}
int OR(vector<int> inputarr) {
return (inputarr[0] == 1 || inputarr[1] == 1);
}
int NOT(vector<int> inputarr) {
if (inputarr[0] != 0) return 0;
else return 1;
}
int (TestClass::* Gate_Func)(vector<int>);
TestClass(int ChooseFunction, vector<int> inputarr) {
InputArr = inputarr;
switch (ChooseFunction)
{
case 1:
Gate_Func = &TestClass::AND;
break;
case 2:
Gate_Func = &TestClass::OR;
break;
case 3:
Gate_Func = &TestClass::NOT;
break;
default:
break;
}
}
void calculation() {
output = Gate_Func(InputArr); //C++ expression preceding parentheses of apparent call must have (pointer-to-) function type
}
vector<int> InputArr;
int output = 2;
void printOutput() { cout << output << endl; }
};
int main() {
vector<int> input = { 1, 1 };
TestClass obj(1, input);
obj.printOutput();
}
Oh! I see, thank you guys, so when I use 'this', it's basically like calling the object of the Class and I have to call the function from that object!
Here is the code:
#include <iostream>
#include <vector>
using namespace std;
class TestClass {
public:
int AND(vector<int> inputarr) {
return (inputarr[0] == 1 && inputarr[1] == 1);
}
int OR(vector<int> inputarr) {
return (inputarr[0] == 1 || inputarr[1] == 1);
}
int NOT(vector<int> inputarr) {
if (inputarr[0] != 0) return 0;
else return 1;
}
int (TestClass::* Gate_Func)(vector<int>);
TestClass(int ChooseFunction, vector<int> inputarr) {
InputArr = inputarr;
switch (ChooseFunction)
{
case 1:
Gate_Func = &TestClass::AND;
break;
case 2:
Gate_Func = &TestClass::OR;
break;
case 3:
Gate_Func = &TestClass::NOT;
break;
default:
break;
}
calculation();
}
void calculation() {
output = (this->*Gate_Func)(InputArr); //C++ expression preceding parentheses of apparent call must have (pointer-to-) function type
}
vector<int> InputArr;
int output = 2;
void printOutput() { cout << output << endl; }
};
int main() {
vector<int> input = { 1, 1 };
TestClass obj(1, input);
obj.printOutput();
}
The functions AND, OR, and NOT are non-static member functions. They can only be called when an instance of their class is supplied.
Gate_Func is a pointer to non-static member function. It can point to a non-static member function such as AND, OR, or NOT. In order to invoke it, you must supply an instance of the class (just as you would have to do in order to call AND, OR, or NOT directly). You also need to supply the arguments to the function.
This is done using a special syntax:
(p->*Gate_Func)(InputArr);
Here, p is a pointer to the instance on which to invoke the function, and InputArr is the argument. If there are multiple arguments, they are separated by commas just like in an ordinary function call.
If you can't remember this syntax, you can also do std::invoke(Gate_Func, p, InputArr). (The instance pointer p goes before all the arguments.)
In your case, I suspect you want to invoke the function on the current instance. You can do this by using this (e.g., (this->*Gate_Func)(InputArr)).
A pointer to a member function requires a pointer to an instance of the type (this) as well as the arguments. The syntax for providing it is fairly ugly:
(this->*GateFunc)(InputArr)
If you have access to C++17, use std::invoke:
std::invoke(GateFunc, this, InputArr)
So I'm trying to print a string, but I get no output. However the other values in the class prints just fine.
In main I have a for loop that prints the the values for the Skill class. In Skill I have a pointer to the Ability class.
class Skill {
private:
Ability* ability;
public:
Ability* GetAbility() {
return ability;
};
}
It gets assigned in the constructor like this:
Skill::Skill(Ability* ability){
this->ability = ability;
}
The Ability class contains just a Name and a score.
class Ability {
private:
string name;
float score;
public:
Ability(string name, float score) {
this->name = name;
this->score = score;
};
string Name() { return name; }
float GetScore() { return score; }
};
Now in main I create a few skills and assign an ability to it. as is a container class that initializes a few ablities in a vector and I can get an ability based on its name.
Skill s* = new Skill[2]
s[0] = Skill(&as.GetAbility("Strength"));
s[1] = Skill(&as.GetAbility("Charisma"));
And then we print
cout << s[i].GetAbility()->Name() << " " << s[i].GetAbility()->GetScore();
However the only output I get is the score. No name what so ever and I can't figure it out. I've tried a few things, but still noting is printing. I'm sure I'm missing something simple that will make me facepalm, but in my defense I haven't written C++ in over 10 years. Thanks in advance.
EDIT: as.GetAbility looks like this:
Ability AbilityScores::GetAbility(string abilityName) {
for (int i = 0; i < abilityScores.size(); i++) {
if (abilityScores[i].Name() == abilityName) {
return abilityScores[i];
}
}
return Ability();
}
abilityScores is a vector
Your AbilityScores::GetAbility() method is returning an Ability object by value, which means it returns a copy of the source Ability, and so your Skill objects will end up holding dangling pointers to temporary Ability objects that have been destroyed immediately after the Skill constructor exits. So your code has undefined behavior.
AbilityScores::GetAbility() needs to return the Ability object by reference instead:
Ability& AbilityScores::GetAbility(string abilityName) {
for (int i = 0; i < abilityScores.size(); i++) {
if (abilityScores[i].Name() == abilityName) {
return abilityScores[i];
}
}
throw ...; // there is nothing to return!
}
...
Skill s* = new Skill[2];
s[0] = Skill(&as.GetAbility("Strength"));
s[1] = Skill(&as.GetAbility("Charisma"));
...
If you want to return a default Ability when the abilityName is not found, consider using std::map instead of std::vector:
private:
std::map<std::string, Ability> abilityScores;
AbilityScores::AbilityScores() {
abilityScores["Strength"] = Ability("Strength", ...);
abilityScores["Charisma"] = Ability("Charisma", ...);
...
}
Ability& AbilityScores::GetAbility(string abilityName) {
// if you don't mind Name() returning "" for unknown abilities...
return abilityScores[abilityName];
// otherwise...
auto iter = abilityScores.find(abilityName);
if (iter == abilityScores.end()) {
iter = abilityScores.emplace(abilityName, 0.0f).first;
}
return iter->second;
}
...
Skill s* = new Skill[2];
s[0] = Skill(&as.GetAbility("Strength"));
s[1] = Skill(&as.GetAbility("Charisma"));
...
Otherwise, return the Ability object by pointer instead:
Ability* AbilityScores::GetAbility(string abilityName) {
for (int i = 0; i < abilityScores.size(); i++) {
if (abilityScores[i].Name() == abilityName) {
return &abilityScores[i];
}
}
return nullptr;
// or:
abilityScores.emplace_back(abilityName, 0.0f);
return &(abilityScores.back());
}
...
Skill s* = new Skill[2];
s[0] = Skill(as.GetAbility("Strength"));
s[1] = Skill(as.GetAbility("Charisma"));
...
So I'm trying to write a recursive function that keeps track of how often it got called. Because of its recursive nature I won't be able to define an iterator inside of it (or maybe it's possible via a pointer?), since it would be redefined whenever the function gets called. So i figured I could use a param of the function itself:
int countRecursive(int cancelCondition, int counter = 0)
{
if(cancelCondition > 0)
{
return countRecursive(--cancelCondition, ++counter);
}
else
{
return counter;
}
}
Now the problem I'm facing is, that the counter would be writeable by the caller of the function, and I want to avoid that.
Then again, it wouldn't help to declare the counter as a const, right?
Is there a way to restrict the variable's manipulation to the function itself?
Or maybe my approach is deeply flawed in the first place?
The only way I can think of solving this, is to use a kind of "wrapper-function" that keeps track of how often the recursive function got called.
An example of what I want to avoid:
//inside main()
int foo {5};
int countToZero = countRecursive(foo, 10);
//countToZero would be 15 instead of 5
The user using my function should not be able to initially set the counter (in this case to 10).
You can take you function as is, and wrap it. One way I have in mind, which completely encapsulates the wrapping is by making your function a static member of a local class. To demonstrate:
int countRecursive(int cancelCondition)
{
struct hidden {
static int countRecursive(int cancelCondition, int counter = 0) {
if(cancelCondition > 0)
{
return countRecursive(--cancelCondition, ++counter);
}
else
{
return counter;
}
}
};
return hidden::countRecursive(cancelCondition);
}
Local classes are a nifty but rarely seen feature of C++. They possess some limitations, but fortunately can have static member functions. No code from outside can ever pass hidden::countRecursive an invalid counter. It's entirely under the control of the countRecursive.
If you can use something else than a free function, I would suggest to use some kind of functor to hold the count, but in case you cant, you may try to use something like this using friendship to do the trick:
#include <memory>
class Counter;
int countRecursive(int cancelCondition, std::unique_ptr<Counter> counter = nullptr);
class Counter {
int count = 0;
private:
friend int countRecursive(int, std::unique_ptr<Counter>);
Counter() = default; // the constructor can only be call within the function
// thus nobody can provide one
};
int countRecursive(int cancelCondition, std::unique_ptr<Counter> c)
{
if (c == nullptr)
c = std::unique_ptr<Counter>(new Counter());
if(cancelCondition > 0)
{
c->count++;
return countRecursive(--cancelCondition, std::move(c));
}
else
{
return c->count;
}
}
int main() {
return countRecursive(12);
}
You can encapsulate the counter:
struct counterRecParam {
counterRecParam(int c) : cancelCondition(c),counter(0) {}
private:
int cancelCondition;
int counter;
friend int countRecursive(counterRecParam);
};
Now the caller cannot modify the counter, and you only need to modify the function slightly:
int countRecursive(counterRecParam crp)
{
if(crp.cancelCondition > 0)
{
--crp.cancelCondition;
++crp.counter;
return countRecursive(crp);
}
else
{
return crp.counter;
}
}
And the implicit conversion lets you call it with an int
counterRecursive(5);
One way to do this is to use a functor. Here's a simple example:
#include <iostream>
class counter
{
public:
unsigned operator()(unsigned m, unsigned n)
{
// increment the count on every iteration
++count;
// rest of the function
if (m == 0)
{
return n + 1;
}
if (n == 0)
{
return operator()(m - 1, 1);
}
return operator()(m - 1, operator()(m, n - 1));
}
std::size_t get_count() const
{
return count;
}
private:
// call count
std::size_t count = 0;
};
int main()
{
auto f = counter();
auto res = f(4, 0);
std::cout << "Result: " << res << "\nNumber of calls: " << f.get_count() << std::endl;
return 0;
}
Output:
Result: 13
Number of calls: 107
Since the count is stored in the object itself, the user cannot overwrite it.
Have you tried using "static" counter variable. Static variables gets initialized just once, and are best candidates to be used as counter variables.
There is a initial game difficulty which is
game_difficulty=5 //Initial
Every 3 times if you get it right, your difficulty goes up to infinity but every 3 times you get it wrong, your difficulty goes down but not below 5. So, in this code for ex:
if(user_words==words) win_count+=1;
else() incorrect_count+=1;
if(win_count%3==0) /*increase diff*/;
if(incorrect_count%3==0) /*decrease difficulty*/;
How should I go about doing this?
Simple answer:
if(incorrect_count%3==0) difficulty = max(difficulty-1, 5);
But personally I would wrap it up in a small class then you can contain all the logic and expand it as you go along, something such as:
class Difficulty
{
public:
Difficulty() {};
void AddWin()
{
m_IncorrectCount = 0; // reset because we got one right?
if (++m_WinCount % 3)
{
m_WinCount = 0;
++m_CurrentDifficulty;
}
}
void AddIncorrect()
{
m_WinCount = 0; // reset because we got one wrong?
if (++m_IncorrectCount >= 3 && m_CurrentDifficulty > 5)
{
m_IncorrectCount = 0;
--m_CurrentDifficulty;
}
}
int GetDifficulty()
{
return m_CurrentDifficulty;
}
private:
int m_CurrentDifficulty = 5;
int m_WinCount = 0;
int m_IncorrectCount = 0;
};
You could just add this as a condition:
if (user words==words) {
win_count += 1;
if (win_count %3 == 0) {
++diff;
}
} else {
incorrect_count += 1;
if (incorrect_count % 3 == 0 && diff > 5) {
--diff
}
}
For example:
if(win_count%3==0) difficulty++;
if(incorrect_count%3==0 && difficulty > 5) difficulty--;
This can be turned into a motivating example for custom data types.
Create a class which wraps the difficulty int as a private member variable, and in the public member functions make sure that the so-called contract is met. You will end up with a value which is always guaranteed to meet your specifications. Here is an example:
class Difficulty
{
public:
// initial values for a new Difficulty object:
Difficulty() :
right_answer_count(0),
wrong_answer_count(0),
value(5)
{}
// called when a right answer should be taken into account:
void GotItRight()
{
++right_answer_count;
if (right_answer_count == 3)
{
right_answer_count = 0;
++value;
}
}
// called when a wrong answer should be taken into account:
void GotItWrong()
{
++wrong_answer_count;
if (wrong_answer_count == 3)
{
wrong_answer_count = 0;
--value;
if (value < 5)
{
value = 5;
}
}
}
// returns the value itself
int Value() const
{
return value;
}
private:
int right_answer_count;
int wrong_answer_count;
int value;
};
And here is how you would use the class:
Difficulty game_difficulty;
// six right answers:
for (int count = 0; count < 6; ++count)
{
game_difficulty.GotItRight();
}
// check wrapped value:
std::cout << game_difficulty.Value() << "\n";
// three wrong answers:
for (int count = 0; count < 3; ++count)
{
game_difficulty.GotItWrong();
}
// check wrapped value:
std::cout << game_difficulty.Value() << "\n";
// one hundred wrong answers:
for (int count = 0; count < 100; ++count)
{
game_difficulty.GotItWrong();
}
// check wrapped value:
std::cout << game_difficulty.Value() << "\n";
Output:
7
6
5
Once you have a firm grasp on how such types are created and used, you can start to look into operator overloading so that the type can be used more like a real int, i.e. with +, - and so on.
How should I go about doing this?
You have marked this question as C++. IMHO the c++ way is to create a class encapsulating all your issues.
Perhaps something like:
class GameDifficulty
{
public:
GameDifficulty () :
game_difficulty (5), win_count(0), incorrect_count(0)
{}
~GameDifficulty () {}
void update(const T& words)
{
if(user words==words) win_count+=1;
else incorrect_count+=1;
// modify game_difficulty as you desire
if(win_count%3 == 0)
game_difficulty += 1 ; // increase diff no upper limit
if((incorrect_count%3 == 0) && (game_difficulty > 5))
game_difficulty -= 1; //decrease diff;
}
inline int gameDifficulty() { return (game_difficulty); }
// and any other access per needs of your game
private:
int game_difficulty;
int win_count;
int incorrect_count;
}
// note - not compiled or tested
usage would be:
// instantiate
GameDiffculty gameDifficulty;
// ...
// use update()
gameDifficulty.update(word);
// ...
// use access
gameDifficulty.gameDifficulty();
Advantage: encapsulation
This code is in one place, not polluting elsewhere in your code.
You can change these policies in this one place, with no impact to the rest of your code.
In the following example
void fun() {
if(int i=SOME_VALUE) {
// ...
} else {
// ...
}
}
What is the scope of i? Can we use it inside the if-block? Can we use it inside the else-block?
Edit:
As a follow-up, in this modified example
void fun() {
if(int i=SOME_VALUE) {
// ...
} else if(int j=SOME_OTHER_VALUE){
// ...
} else {
// ...
}
}
Can we access both i and j in the else clause?
Yes, and yes.
A typical use for this is dynamic casting:
if (auto p = dynamic_cast<Derived*>(base_pointer))
{
// p is a Derived*
}
else
{
// not the right dynamic type
}
Another construction I've been finding useful:
if (auto fp = std::unique_ptr<FILE, int(*)(FILE*)>(std::fopen("file.txt", "rb"), std::fclose))
{
// file exists, use fp.get()
}
else
{
// file does not exist
}
And one more:
if (pid_t pid = fork())
{
waitpid(pid, nullptr, 0);
}
else
{
execl("/bin/rm", "/bin/rm", "-rf", "/", static_cast<char*>(nullptr));
}
Yes, you can use the variable declared in the if condition in the else substatement like your example.
However, if you declare i inside the if substatement like this:
if (some_condition) {
int i = 42;
// ...
} else {
std::cout << i; //error
// ...
}
in the else part, the variable i is no longer in scope.
Yes, because the variable is "created" in the outermost scope and only then, evaluated in the if condition. Your code could be rewritten like:
int i = SOME_VALUE;
if(i) {
// ...
} else {
// ...
}
and not like:
if(SOME_VALUE) {
int i = SOME_VALUE;
// ...
} else {
// ...
}
as you may have though.
The second question can be answered the same way.