I'm trying to use a boolean value to keep the state I'm in.
In my header file, I declare:
bool *modified;
In my class constructor I initialize the state at false:
bool initState = false;
modified = &initState;
I then have a button that change the state to true:
bool change = true;
modified = &change;
I also have a button to see the state:
if(!*modified){
// doing something
} else{
// do something else
}
The issue is if I actually changed the state, !*modified will still be at true. I'm at a loss to see where the problem lies. Does anyone have any ideas where it is.
You are changing the value of modified, which is a bool*, and maybe to point to stack-allocated data which will be destroyed on function return. You want to change the value which is pointed to by modified.
bool initState = false;
*modified = initState;
bool change = true;
*modified = change;
This is assuming that the modified pointer is actually allocated somewhere.
Try this.
if (!(*modified))
else
bool change = true;
*modified = change;
bool initState = false;
*modified = initState;
try this code
bool *modified;
bool initState = false;
modified = initState; false
bool change = true;
modified = change; true
if ( *modified != initState)
{
do something
}
else
{
do something
}
Related
if (GetKeyState(VK_DOWN) & 0x80)
{
func();
}
It calls func() like 4 times when I press key
I want it to call only once when I press key
EDIT:
SHORT keyState;
SHORT keyState2;
SHORT keyState3;
static bool toogle1 = false;
static bool toogle2 = false;
static bool toogle3 = false;
if (keyState = GetAsyncKeyState(VK_DOWN) && !toogle1)
{
toogle1 = true;
}
else
toogle1 = !toogle1;
if (keyState2 = GetAsyncKeyState(VK_NUMPAD0) && !toogle2)
{
toogle2 = true;
}
else
toogle2 = !toogle2;
if (keyState3 = GetAsyncKeyState(VK_NUMPAD1) && !toogle3)
{
toogle3 = true;
}
else
toogle3 = !toogle3;
Here is how I did it, will it work?
static bool once = false;
if (GetKeyState(VK_DOWN) & 0x80)
{
if (!once)
{ once = true; func(); }
}
I guess you run this in a loop. Your idea with toggling a flag when called is not bad, but since you toggle it back in the else case, you call func() half as often as before (every 2nd time).
When you want to call it again (I think you want, according to your code), when the key is pressed again, but not spam the function call, you can use a variable to store which key was pressed last and only call func(), when it was another key (you can also add a "no key pressed" state.
If you really just want to call it once, just remove your else statements.
Consider these code happen in real life.
A library code has a function called log_on(), it returns false on fail, true on success, but it has too many false cases.
Before return true/false, it needs to call a callback function application specified. So it looks like:
bool log_on() {
// do something else
bool success = false;
scope_guard guard = [&success]() {
if (success) {
callback(success);
} else {
callback(false);
}
}
success = prepare_logon();
if (success) {
int rc = send_password();
if (rc == PASSWORD_ERR) {
return false;
}
}
if (!send_some_data()) return false;
success = true;
return true;
}
The purpose is too many return cases, and need to call some callbacks if true and false is returned. So someone use scopeguard to do this. Is this a good practice to replace return check with scopeguard use? And in this case, the library code is required not to throw, if user specify a function callback that will throw, so error handling is a problem?
If I had to do this, I'd move the real work into a helper function:
bool log_on_impl() { /* real work here*/ }
bool log_on() {
bool success = log_on_impl();
callback(success);
return success;
}
This way, log_on_impl could do early returns to its heart's content; the callback will still be called with the correct value.
I want to do something like this :
bool val = false;
bool val1 = false;
...
void function(&val,&val1,...)
{
val = false;
val1 = true;
val15 = false
...
}
I know how to pass a variable number of arguments to a function (va_arg) however i don't know how to do the same with references. Thank you for your help and i'm sorry for the stupid question.
I have a vector of pointers to class instances I created with multiple values in it called Record
it has a value called, when I access them I
bool recordDeleted;
bool recordOwnership;
vector<Record*> RecordsVec
I want to create a function that would do something like,
bool func()
{
for (auto it = RecordsVec.begin(); it < RecordsVec.end(); it++)
{
// check whether recordDeleted is true // or recordOwnership == true)
}
// if all are true
// return true
// else
// return false
}
what is the most efficient way to do this ?
Pretty simple:
bool allDeleted() {
return std::all_of(begin(RecordsVec), end(RecordsVec), [](Record *r) {
return r->recordDeleted;
});
}
And the same for your ownership flag, of course.
How to correct return created std::list through function argument? Now, I try so:
bool DatabaseHandler::tags(std::list<Tag> *tags)
{
QString sql = "SELECT * FROM " + Tag::TABLE_NAME + ";";
QSqlQueryModel model;
model.setQuery(sql);
if(model.lastError().type() != QSqlError::NoError) {
log(sql);
tags = NULL;
return false;
}
const int count = model.rowCount();
if(count > 0)
tags = new std::list<Tag>(count);
else
tags = new std::list<Tag>();
//some code
return true;
}
After I can use it:
std::list<Tag> tags;
mDB->tags(&tags);
Now, I fix my function:
bool DatabaseHandler::tags(std::list<Tag> **tags)
{
QString sql = "SELECT * FROM " + Tag::TABLE_NAME + ";";
QSqlQueryModel model;
model.setQuery(sql);
if(model.lastError().type() != QSqlError::NoError) {
log(sql);
*tags = NULL;
return false;
}
const int count = model.rowCount();
if(count > 0)
*tags = new std::list<Tag>(count);
else
*tags = new std::list<Tag>();
for(int i = 0; i < count; ++i) {
auto record = model.record(i);
Tag tag(record.value(Table::KEY_ID).toInt());
(*tags)->push_back(tag);
}
return true;
}
It works but list return size 4 although loop executes only 2 iterations and empty child objects (if I just called their default constructor). The Tag class hasn't copy constructor.
Since you passed an already instantiated list as a pointer to the function, there is no need to create another list.
In that sense, you question is pretty unclear. I'd suggest you read up a bit on pointers, references and function calls in general.
http://www.cplusplus.com/doc/tutorial/pointers/
http://www.cplusplus.com/doc/tutorial/functions/
UPDATE: I still strongly suggest you read up on the mentioned topics, since you don't know these fundamental points.
Anyway, this is what you probably want to do (event though I would suggest using references, here is the solution with pointers):
bool someFunc(std::list<Tag> **tags) {
// by default null the output argument
*tags = nullptr;
if (error) {
return false;
}
// dereference tags and assign it the address to a new instance of list<Tag>
*tags = new std::list<Tag>();
return true
}
std::list<Tag> *yourList;
if (someFunc(&yourList)) {
// then yourList is valid
} else {
// then you had an error and yourList == nullptr
}
However, this is not idiomatic C++. Please read a modern book or tutorial.
Use a reference.
bool DatabaseHandler::tags(std::list<Tag>& tags);
std::list<Tag> tags;
mDB->tags(tags);
You'll have to change all the -> to ., of course. Every operation done on the reference in the function will be done to the original tags list it was called with.
EDIT: If you want to create the list inside the function and return it, you have a couple options. The closest, I think, is to just return a list pointer, and return nullptr if the function fails.
//beware, pseudocode ahead
std::list<Tag>* DatabaseHandler::tags() //return new list
{
if (success)
return new std::list<Tag>(...); //construct with whatever
else
return nullptr; //null pointer return, didn't work
}
std::list<Tag> tags* = mDB->tags();
You could alternatively have it return an empty list instead, depending on how you want it to work. Taking a reference to a pointer would work the same way, too.
bool DatabaseHandler::tags(std::list<Tag>*&); //return true/false
std::list<Tag>* tags;
mDB->tags(tags); //tags will be set to point to a list if it worked