I'm new to C++, and I'm learning Qt.
Consider this line:
connect(ui->horizontalSlider, &QSlider::valueChanged,
ui->progressBar, &QProgressBar::setValue);
What I don't understand is why you pass the address of a static (is it static?) method valueChanged (&QSlider::valueChanged) instead of the current object method address &ui->horizontalSlider->valueChanged. Although I can use this second option that works too.
You pass the address of the member function which should be called.
The member function is not static though, that means it needs an object to work on.
class MyClass
{
void aFunction();
}
here MyClass::aFunction is a member function.
What the compiler creates is similar to this
class MyClass
{
static void aFunction(MyClass *this);
}
So whenever you call aFunction like my_instance.aFunction() the this pointer will be handed over implicitly, so the call basically becomes MyClass::aFunction(&my_instance).
As a result the address of aFunction is the same for every instance of MyClass.
Yet to execute aFunction you need an instance of MyClass.
This is why in your case you have to provide connect with both the instance ui->horizontalSlider as well the function to be called on it &QSlider::valueChanged.
What I described is an oversimplification so take it with a grain of salt.
Moreover when you have virtual functions things change.
Related
I'm trying to pass a virtual method to the thread class' constructor (C++ thread).
After searching all over, I've only been able to pass a non-virtual member method.
My base class A has a start method as follows:
void A::start() {
thread(&A::runnable,A()); // <--- What do I change here?
}
The function runnable is virtual and is also implemented in derived class B.
I override runnable in derived class B.
I then invoke start on B.
Obviously, and undesirably, the start function uses runnable implemented in A (instead of B) because it is explicitly defined in A::start.
Is there any way to let the runnable function be dynamically bound?
I thought of using templates and a couple of other creative solutions. (I eventually will implement start in B if there are no real solutions)
Any help would be greatly appreciated.
Obviously, and undesirably, the start function uses runnable implemented in A (instead of B) because it is explicitly defined in A::start.
This could be obvious to you, but it is incorrect. When you create a thread you pass an unnamed temporary instance of class A, which obviously has type A so A::runnable would be always called, but you should pass this:
void A::start() {
thread(&A::runnable,this); // <--- What do I change here?
}
Then proper virtual function would be called.
See Boost::Bind and virtual function overloads: why do they work? for details why.
There are a couple of things to address.
First in A::start() you create an anonymous local thread object. Unfortunately, this object will be destructed as soon as you leave A::start(). This will trigger an abort.
When you create a thread object you must always either join() it or detach() it before the object gets destructed.
For the rest of the answer, I'll use a private thread t in A:
class A {
...
protected:
thread t; // default constructed thread object, i.e. without associated thread of execution
public:
...
~A() {
if (t.joinable()) // If thread active and not detached, be sure that it's joined before it is destructed !!
t.join();
}
....
};
Next, in your thread creation, you use A() as parameter. This means that you will create a new anonymous A object and pass it as argument. I guess it's not what you intend to do, so you use this instead.
Then, as was told by Slava, when &A::runnable is used in combination with this, it is the virtual function that is called. So start() should look like:
void start() {
t = move (thread (&A::runnable, this )) ; // Here I create an anonymous thread and move it to t.
}
If your run this code, you'll notice that A::runnable() is called for class A objects and B::runnable() for class B objects.
As I understood pointers to non-static methods, they're no more useful than for providing an alias mechanism for a certain method. For example, having an object with three methods
class Provider
{
public:
int A(int in);
int B(int in);
int C(int in);
}
and a consumer that requires a pointer to a provider method (be it A, B or C). Having a controller that gives a pointer to one of the 3 methods to the so-called consumer, we can write something in the consumer code that uses a Provider instance and the pointer to either A, B or C, depending on what the controller sent.
If this is all that a pointer to a non-static method in C++ can do, is there still a way of providing a more "intelligent" pointer to an object's method, without sending the object along with that method pointer to a consumer? In the affirmative case, what's the idiom/mechanism called (even a way to simulate this qualifies as an answer I'm interested in).
Your concept of member functions pointers is correct in general.
Member functions pointers are actually very useful with conjunctions to such helpers, as std::bind, or std::function. Raw member function pointers are usually ugly.
As for your example,
Your consumer can accept std::function<return_type(args)> and you can pass binding of object and its member function to such consumer.
such structs as std::bind also allows realization of such concepts as partial specialization and currying.
The whole point of a "pointer to member function" is so you can call a named method on any object (of the correct class). So, no, there is no way to "hide" the object reference inside the pointer.
You can always write your own wrappers for stuff like this; that's what the various callback mechanisms for C++ do to give you a more convenient API for the application at hand.
You dont have to glue pointer to object with pointer to method to be called, you can provide pointer to instance any time, ie:
class CClass {
public:
void func(int a) {}
};
///
std::function<void(CClass&, int)> call_func = &CClass::func;
///
CClass cls1;
CClass cls2;
call_func(cls1, 1);
call_func(cls2, 2);
Is there a way to call a non static class member method from another method that is contained within the main class in c++? If so, what would the code look like?
Problem is, I can't declare this specfic method as static, because it uses other methods within the same class that then don't work if I make the one static.
I'm trying to use:
MyClass::myClassMethod();
from a method within the main class, but it gives me the error: a non static member reference must be relative to a specific object.
To clarify, myClassMethod() uses other methods within MyClass like:
void myClassMethod() {
...
anotherClassMethod();
}
so if I were to make myClassMethod static it would interfere with calling anotherClassMethod().
What is the deal with calling non-static member function from a static member function?
Every non static member function is passed an this pointer implicitly in addition to the parameters you pass, the pointer passed is then dereferenced to refer class object members However static functions are not passed with the implicit thispointer and hence one cannot call any non static member function inside a static member function because there is no this to do so.
What is the solution, If you want to do it anyways?
You will need some mechanism to get the pointer to the object inside the static method and then you can call the member function using that pointer.
How to do that?
You will have to store the pointer to class object globally, or pass it as an instance in one of the function arguments to the static method.
However, both of above are workarounds, the important thing to note here is If you feel the need of calling a non static member function through a static member function then there is something wrong in your design.
On Second thoughts maybe I mis-read your Question before, Probably, Your question is:
How to call a non-static member function of a class from main?
You need a instance of the class to call non-static member functions.
So simply,
MyClass obj;
obj.myClassMethod();
And calling any other member function from within myClassMethod() would simply be:
void myClassMethod()
{
//...
anyOtherMyClassNonStaticMemberFunction();
//...
}
A static method is one that doesn't run on any particular object. It's a lot like a standalone function outside of a class, except that it's allowed to access private members in its class.
If you anotherClassMethod() is non-static, that means it has to be called on a specific object, an instance of the class. Because it's called on an object, it can access data stored in that object (non-static member variables). If myClassMethod() is static and you implement it as
void MyClass::myClassMethod() {
anotherClassMethod();
}
That won't work because anotherClassMethod() expects to be called on a specific object, but myClassMethod() doesn't have one. But if you know what object you want to call it on, you can do it as an ordinary method call on an object:
void MyClass::myClassMethod(MyClass &object) {
object.anotherClassMethod();
}
The object doesn't have to be passed in as an argument; it could be a static member variable in the class, for example:
class MyClass {
private:
static MyClass theInstance;
// ...
};
void MyClass::myClassMethod() {
theInstance.anotherClassMethod();
}
Ultimately, the question you need to ask yourself is: why is myClassMethod() static, and why is anotherClassMethod() non-static? Take a step back, think about what myClassMethod() is supposed to do. Does it make sense to call it when you don't have an instance to work with? If so, why does it need to call a method that expects to work with an instance?
The only way to call a non static method of a class is through an instance of that class. So you would need something like this...
MyClass myClass;
myClass.myClassMethod();
I think that maybe you could use the singleton pattern, keep a instance of the class in global. like a utility class.
I'm having a little problem with inheritance in C++ that I can't quite figure out.
So, say I have some classes derived from stl list, i.e:
class Class1: public list<T>{
virtual func1();
}
class Class2 : public Class1<w/e>{
func1();
}
The problem I'm having is when passing these to a function. How can I properly pass an instance of one of these to a function so that it will use the proper virtual function if it is possible for an instance of either type to be passed? I haven't done inheritance and virtual functions in awhile so I am a bit rusty here.
(This assuming that the function is not a member function of the classes).
You will need to pass them to the function as a reference
int function(Class1& obj);
or as a pointer;
int function(Class1* obj);
and it should just plain call the correct version of the virtual method.
If you pass them without either of those
int function(Class1 obj);
The object will be copy constructed to always be a Class1 in the function, and will always call Class1::func1()
I want to call the base class implementation of a virtual function using a member function pointer.
class Base {
public:
virtual void func() { cout << "base" << endl; }
};
class Derived: public Base {
public:
void func() { cout << "derived" << endl; }
void callFunc()
{
void (Base::*fp)() = &Base::func;
(this->*fp)(); // Derived::func will be called.
// In my application I store the pointer for later use,
// so I can't simply do Base::func().
}
};
In the code above the derived class implementation of func will be called from callFunc. Is there a way I can save a member function pointer that points to Base::func, or will I have to use using in some way?
In my actual application I use boost::bind to create a boost::function object in callFunc which I later use to call func from another part of my program. So if boost::bind or boost::function have some way of getting around this problem that would also help.
When you call a virtual method via a reference or a pointer you will always activate the virtual call mechanism that finds the most derived type.
Your best bet is to add an alternative function that is not virtual.
What you're trying to do unfortunately isn't possible. Pointer-to-member-functions are designed to maintain the virtualness of the function pointed-to.
Your problem is that a member function pointer is not quite the same as a bare function pointer. It actually isn't just a pointer, but a considerably more complex structure, which varies in its details at the level of the compiler implementation. When you invoke it via the syntax (this->*fp)() you are actually calling it on the original object, which causes virtual function dispatch.
One thing that might work is to cast it to a non-method pointer type. This is a little creaky but I think it should work. You still need to pass a Base * but you do it explicitly and the virtual function dispatch is by-passed:
typedef void BasePointer(Base*);
void callFunc()
{
BasePointer fp = (BasePointer *)&Base::func;
fp(this);
}
Update: Ok, no, you can't do it that way. It's illegal, and wouldn't be safe it if it was legal. The C++ FAQ has more on this. But knowing that doesn't solve your problem. The issue is that, pointer-to-object or pointer-to-member if you want to call Base::func through a Base pointer, the object it is pointing must also be a Base. If you can arrange that, then you can use a member function pointer.
Here's another thought, not pretty, but at least workable. Provide a function in Derived, non-virtual, that explicitly calls Base::func. Point to that instead. It won't scale if you need to do this in the general case of lots of different variants of func and callFunc but it will work fine for one method.
Is there any specific reason for doing this via a function pointer?
You should be able to just write:
Base::func();
to call the base class implementation.
In addition to what quark says, a more general remark is that you should use a signal/slot implementation rather than a bare function pointer. Boost has one, there's libsigc and a bunch of others.
What's wrong with this?
(Base(*this).*fp)();
Now if you're satisfied with that, it raises the question of why you're even using a function pointer in the first place. I think some more context might help.