Shoud i use slots in other methods [closed] - qt

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
Is it normal to use slots in other methods? Like here i use releaseIncrement() in Increment() to avoid code duplication:
#include "counter1.h"
#include <iostream>
Counter1::Counter1(int startValue)
{
m_count = startValue;
}
int Counter1::getValue()
{
return m_count;
}
int Counter1::Increment()
{
std::cout <<"In class: " <<this <<" method Increment() was called" <<std::endl;
releaseIncrement(); // I used slot here to avoid code duplicate
emit wasIncremented();
return m_count;
}
int Counter1::Decrement()
{
std::cout <<"In class: " <<this <<" method Increment() was called" <<std::endl;
releaseDecrement(); // I used slot here to avoid code duplicate
emit wasDecremented();
return m_count;
}
void Counter1::releaseIncrement()
{
m_count++;
std::cout <<"In class: " <<this << " m_count was incremented by releaseIncrement() methos. Now m_count is: " <<m_count <<std::endl;
}
void Counter1::releaseDecrement()
{
m_count--;
std::cout <<"In class: " <<this << " m_count was decremented by releaseDecrement() methos. Now m_count is: " <<m_count <<std::endl;
}
It works and works correct, but i feel like I am doing something bad, like it is bad practice. Can you suggest me something?

If you're asking whether you can use slot functions as ordinary functions, the answer is yes - there's nothing special about slots. You can use them anywhere.

Related

Using requests to verify command success

Lets say Typed Actor A needs to command Typed Actor B to do something. Actor A also needs to know if the command ran succesfully or not but does not want to block operation until this response arrives. My current working theory is that this is best satisfied with Requests. More specifically request(...).then
There is a nice example called "request.cpp" that I have been playing with. My challenge is that I don't really need actor B to return any data. I just need to know if the command was successful or not and if not what error was thrown.
So my question is two fold: 1) Am I correct in thinking that request(...).then is the correct mechanism to do what I want and 2) if so then can a request handle a response that has no data?
This is what I'm trying:
#include <chrono>
#include <cstdint>
#include <iostream>
#include <vector>
#include "caf/all.hpp"
using std::endl;
using std::vector;
using std::chrono::seconds;
using namespace caf;
using cell
= typed_actor<result<void>(get_atom, int32_t)>;
struct cell_state {
static constexpr inline const char* name = "cell";
cell::pointer self;
cell_state(cell::pointer ptr) : self(ptr) {}
cell_state(const cell_state&) = delete;
cell_state& operator=(const cell_state&) = delete;
cell::behavior_type make_behavior() {
return {
[=](get_atom, int32_t input) -> result<void> {
if (input != 5) { // Simulate command successful or not
return; // If successful, then return;
}
else {
return sec::unexpected_message; // If not then return error.
}
},
};
}
};
using cell_impl = cell::stateful_impl<cell_state>;
void multiplexed_testee(event_based_actor* self, vector<cell> cells) {
for (cell& x : cells) {
aout(self) << "cell #" << x.id() << " calling" << endl;
self->request(x, seconds(1), get_atom_v, static_cast<int32_t>(x.id()))
.then(
[=](void) {
aout(self) << "cell #" << x.id() << " -> " << "success" << endl;
},
[=](error& err) {
aout(self) << "cell #" << x.id() << " -> " << to_string(err) << endl;
});
}
}
void caf_main(actor_system& system) {
vector<cell> cells;
for (int32_t i = 0; i < 5; ++i)
cells.emplace_back(system.spawn<cell_impl>());
scoped_actor self{ system };
auto x2 = self->spawn(multiplexed_testee, cells);
self->wait_for(x2);
}
CAF_MAIN()
When I compile, I get an error on the empty return statement saying "return-statement with no value, in function returning caf::result<void>. Is there a better way to do this?
My backup plan is to change my command definition to just return a standard error and return sec::none if the operation was successful. But I'm afraid that approach violates the spirit of the whole optional-second-parameter for error conditions. How well am I thinking about all this?
Is there a better way to do this?
You had the right idea. The result<void> expects either an error or a 'void' value. Since void{} isn't a thing in C++, you can do return caf::unit; to tell result<void> to construct an "empty" result. On the receiver's side, you already did the right thing: then with a lambda taking no arguments.
Minor point:
[=](void) { ... }
This is a C-ism from the early days where the compiler allowed you to do silly things. Just drop the void, it serves no purpose. :)

'this' pointer changes in c++11 lambda

I found a very strange problem with this pointer in c++11's lambda.
#include <string>
#include <iostream>
using namespace std;
#include <boost/signals2.hpp>
boost::signals2::signal<void()> sig;
struct out {
void print_something() {
cout << "something" << endl;
}
out() {
auto start = [&] {
cout << "this in start: " << this << endl;
this->print_something();
};
cout << "this in constructor: " << this << endl;
// sig.connect(start);
sig.connect([&] {
cout << "this in signal: " << this << endl;
start();
});
this->print_something();
}
};
int main() {
out o;
sig();
}
The code prints three this(s) pointer at different location. I was expecting that all the three this pointer should be the same value, but they are not. Here's the output:
this in constructor: 00F3FABB
something
this in signal: 00F3FABB
this in start: 00F3FB00
something
Question 1: Why is this in start has different value? How to correct it?
Question 2: Since the this in start is a different pointer, it shouldn't be able to call print_something(). I would expect a crash on this but it works fine. Why?
You capture start by reference, but the variable start and the contained lambda function get destroyed at the end of out().
Later the signal handler tries to call start(), but the lambda function doesn't exist anymore. Maybe the memory where its this was stored was overwritten in the mean time, causing unexpected output.
The call to print_something() doesn't crash despite of the invalid this because the function doesn't actually try to use this. The printing in the function is independent of this and the lookup of print_somethings address can happen at compile time so that calling the function doesn't access this at runtime.

STRCPY is undefined c++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
Im attempting to implement strcpy or strncpy and both are showing an error no matter which i use.
The error is only under strncpy and strcpy
Item.cpp:
#include "Item.h"
#include <iomanip>
#include <iostream>
#include <ctime>
#include <string>
using namespace std;
#include "Date.h"
#include "POS.h"
#include "PosIO.h"
namespace sict {
Item::Item(){
_name = '\0';
_price = 0;
_taxed ='0';
_quantity = '\0';
}
Item::Item(const char* sku, const char * name, double price, bool taxed){
strNcpy(_sku, sku, MAX_SKU_LEN);
name = new char[20];
strcpy(_name, name);
_quantity = 0;
price = _price;
if (price = '\0') {
_taxed = true;
}
}
void Item::sku(const char* value){
strncpy(_sku, value);
}
void Item::price(double p){
p = _price;
}
void Item::name(const char * n){
strcpy(_name, n);
}
}
Any idea how to fix it, ive excluded alot of code from item.cpp thats irrelevant.
Both strcpy and strncpy are declared in the cstring header. You need to include it in order to use the functions:
#include <cstring>
Using std::strcpy();
will solve your issue.
There are two ways to solve this problem, either by including the appropriate header which is #include <cstring> or put std:: in front of the function.
Also, I have noticed that you write strNcpy which can lead to a syntax error.

Storing local dynamic_pointer_cast<>() in outer scope

In the following piece of code, I'm retrieving a shared_ptr<A> from a function. I then dynamically cast the pointer to a deriving class and store it in a shared_ptr<B>. The original pointer is not a nullptr.
shared_ptr<B> storage = nullptr;
if (...)
{
shared_ptr<A> definition = getSharedPointer();
// Store the lambda
storage = dynamic_pointer_cast<B>(definition);
}
I would expect the dynamic_pointer_cast and storage to storage to increase the total reference count to 2. Then, when I leave the scope of the if-statement, storage's reference count should be one.
Yet, when I tried to call a method on storage, I get a EXC_BAD_ACCESS, implying I'm reading in a deleted pointer.
storage->foo(...)->bar(...);
Is my logic wrong? Is this a bug in clang (can't imagine)?
EDIT
I seem to have found the error, which has nothing to do with the pointers. The function bar() actually gave the problem. If anyone ever reads this: the above code is perfectly valid.
This example works fine:
#include <memory>
using namespace std;
struct A {
virtual ~A() {}
};
struct B : A {};
shared_ptr<A> getSharedPointer() {
return make_shared<B>();
}
#include <iostream>
int main() {
shared_ptr<B> storage = nullptr;
if (true)
{
shared_ptr<A> definition = getSharedPointer();
// Store the lambda
storage = dynamic_pointer_cast<B>(definition);
}
cout << storage.get() << endl;
}
It would seem that your shared_ptr<A> is not pointing to a B and the result of the dynamic_pointer_cast is nullptr. Maybe a debugging statement would be helpful:
if (...)
{
shared_ptr<A> definition = getSharedPointer();
cerr << "as A: " << definition.get()
<< ", as B: " << dynamic_cast<B>(definition.get()) << endl;
// Store the lambda
storage = dynamic_pointer_cast<B>(definition);
}

how to simulate and get "bad_alloc "exception?

Can anyone tell me how to simulate and produce the bad_alloc exception in C++? In my code in some places i am using new operator which will throw the bad_alloc exception. I want to simulate this scenario and need to test the code.
Balamurugan,
I had the same doubt this afternoon, and did not see anything related here.
So I went to CPlusPlus and put the try catch inside an infinite loop, and worked. Under VS C++ 2010 Express.
Below my code:
// bad_alloc standard exception
#include <iostream>
#include <exception>
using namespace std;
int main ()
{
unsigned int count=0;
while (1)
{
count++;
try
{
int* myarray= new int[1000000];
}
catch (exception& e)
{
cout << "Standard exception: " << e.what() << endl;
cout << "\nAborting after "<< count << " loops";
return -1;
}
}
cout<<"\nNormal finishing...";
return 0;
}
In my case, it was caught after 523 loops. I would be better if i knew a setting to limit the heap to Fisical Memory, if I find I'll make you know.

Resources