Qt c++ nested classes / solve illegal call of non-static member function - c++

I'm dealing with sample code from a camera SDK, and I have issues getting the frame data "outside" the CSampleCaptureEventHandler class.
class DahengCamera : public QObject
{
Q_OBJECT
class CSampleCaptureEventHandler : public ICaptureEventHandler
{
void DoOnImageCaptured(CImageDataPointer& objImageDataPointer, void* pUserParam)
{
[grab some data ...]
CopyToImage(objImageDataPointer); // illegal call of non-static member function
}
};
public:
DahengCamera();
~DahengCamera();
private:
void CopyToImage(CImageDataPointer pInBuffer); // I want to have my frame datas here
QImage m_data; //and here
};
I'm using a callback register call to make the camera "DoOnImageCaptured" event called once a frame is grabbed by the system. But I'm stuck getting the data outside this method. CopyToImage() is supposed to get a reference to QImage or to write into m_data, but I have "illegal call of non-static member function" errors. Tried to make CopyToImage() static, but it just move the problem...
How can I solve this ?
Thanks !

CopyToImage is a private non-static function in the class DahengCamera.
The fact that CSampleCaptureEventHandler is a nested class inside DahengCamera allows it to access DahengCamera's private members and functions (as if it were decleared a friend class), but this does not provide CSampleCaptureEventHandler with a pointers to any DahengCamera objects.
You need to provide the actual instance of the CSampleCaptureEventHandler object on which DoOnImageCaptured is called with a pointer/refence to the DahengCamera object on which CopyToImage should be called. You might consider providing this pointer/reference to the DoOnImageCaptured object to CSampleCaptureEventHandler's constuctor (i.e. dependency injection).
(And - for your own sake - do not try to "fix" this by turning CopyToImage or m_data into static - this would create only a horrible mess)

Related

How does C++ knows child class calls a parent method?

I don't know how to summarize my question so couldn't find an answer on Google.
When overriding a parent method,
void Child::method(){
//stuff
Parent::method();
}
Works perfectly. But the parent method requires the information from the Child class instance to work properly, which is not given as arguments. So my question is, does C++ have a mechanism to let the Parent know which instance of a Child class calls a Parent method, like without doing Parent::method(this) ?
The thing that makes me think this is, if you do something like this,
int main(){
SomeParentClass::someMethod();
}
It gives: error: call to non-static member function without an object argument. So the compiler needs to know the instance, which was not also given in the child class. But did not raise an error so it must have known the instance.
Edit: I added the Qt tag because I am experimenting on a Qt class. So that I can give an example if needed.
Edit2:
devicedialog.h
class DeviceDialog : public QDialog
{
Q_OBJECT
public:
explicit DeviceDialog(QWidget *parent = nullptr);
int exec() override;
~DeviceDialog() override;
}
devicedialog.cpp
int DeviceDialog::exec(){
// My code.
return QDialog::exec();
}
exec() function activates and shows a QDialog on the screen. However, that way it is called, it seems like the parent method has no way of knowing which dialog to show (no parameters passed). The only knowledge could be the identity of the instance calling it. I am just asking if this knowledge transferred to the method in the background.
I think you are just being confused by the language's attempt to make things easier on you. Your example function is equivalent to
void Child::method(){
//stuff
this->Parent::method();
}
Just as you cannot call a (non-static) method in the child class without an object, you cannot call the parent's method without an object. However, the context is the body of such a method. Within the body, the context is assumed to be *this. Just as you can refer to data members without explicitly prefixing "this->", you can call methods without the prefix.
This is nothing special to member functions of a parent class. Calling a function of the child class via explicitly naming the type:
Child::method();
works in exactly the same way in this regard. Used outside of a member functions definition it causes the same error.
The relevant paragraph of the standard is §9.3.1:
When an id-expression that is not part of a class member access syntax
and not used to form a pointer to member is used in a member of class
X in a context where this can be used, if name lookup resolves the
name in the id-expression to a non-static non-type member of some
class C, and if either the id-expression is potentially evaluated or C
is X or a base class of X, the id-expression is transformed into a
class member access expression using (*this) as the postfix-expression
to the left of the . operator.
So, in other words, the call
Parent::method();
inside a member function is transformed into something akin to
(*this).Parent::method();
This is still a c++ specific question. Qt just utilizes it. You need to study objects, inheritance, and virtual methods.
void Child::method() {
Parent::method();
// this->Parent::method();
}
The above works because the child has access to the parents methods (that are not private). Because the method is an override of the parents virtual method, the only way for the compiler to know you want to call the parents method is to call it with scope resolution '::' in the child.
int main() {
SomeParentClass::someMethod();
}
The above does not work because there is no instantiated object. When you call a method, you call it on the object (unless it is a static method). So instead you would do something like:
int main() {
SomeParentClass parent;
parent.someMethod();
ChildClass child;
child.someMethod(); // accesses the childs overridden method and not the parents.
}

Private/Protected variable "error: within this context"

I have a class based off of the SFML gamefromscratch.com tutorials, called "VisibleGameObject" Within this class, is a private variable "_sprite", as well as a "getSprite()" function that I tried as both protected and public. (Even as public, it still says "_sprite" is private even though the public function returns the variable).
In my OnRender class, I create two VisibleGameObjects.
VisibleGameObject _testtile1;
VisibleGameObject _cursorSprite;
But when I draw to draw the sprites, I get the error: within this context.
_mainWindow.draw(_cursorSprite._sprite);
alternatively I tried (with getSprite() being protected or public).
_mainWindow.draw(_cursorSprite.getSprite());
Yet always, "error: 'sf::Sprite VisibleGameObject::_sprite' is private. error: within this context"
Doesn't make any sense to me, because
1) _sprite is a variable of VisibleGameObject. It may be private, but it is not being accessed by anything but its own original class of "VisibleGameObject". I thought classes could access their own variables, even when they're a new instantiated object in another class?
2) getSprite() is public, and returns the private variable, yet it is STILL saying _sprite is private? This makes no sense to me! Everything I have learned about Getters and Setters, says that the public function CAN return a private variable, as that is the whole point of this Getter.
sf::Sprite& VisibleGameObject::getSprite()
{
return _sprite;
}
class VisibleGameObject
{
public:
VisibleGameObject();
virtual ~VisibleGameObject();
private:
sf::Sprite _sprite;
protected:
sf::Sprite& getSprite();
OR
public:
sf::Sprite& getSprite();
Protected members of a class can only be accessed by the class itself and classes which are derived from it.
Since you are calling the draw function not from within a class that was derived from VisibleGameObject you get an error.
You propably should read this:
http://www.cplusplus.com/doc/tutorial/inheritance/

C++: call (derived's) member function on base pointer of a different derived class's object

Is it "safe" (and/or portable) to call a member function (pointer) on the pointer of a base class, but the object pointed to is an instance different derived class. The member function does not access any member variables or functions of the derived class.
/* Shortened example of what happens in the client code and library */
class Base { /* ... */ }
class DerivedA : public Base {
/* ... */
public: void doSomethingA(float dt);
}
void DerivedA::doSomethingA(float dt) {
/* Does not access members. Conventionally calls/accesses statics */
cout << "dt(" << dt << ")";
}
class DerivedB : public Base { /* ... */ }
typedef void (Base::*SEL_SCHEDULE)(float);
SEL_SCHEDULE pCallback = (SEL_SCHEDULE)(&DerivedA::doSomethingA);
DerivedB db = new DerivedB();
Base *b = &db;
/* pCallback and b are saved in a list elsewhere (a scheduler) which calls */
(b->*pCallback)(0.f);
This seems to work (in MSVC/Debug mode) okay at runtime, but I'm wondering whether this is Bad (TM) - and why? (I'm yet to test this code with the compilers for Android and iOS).
Some more specifics if required: I'm building a cocos2d-x based project. Base is CCObject, DerivedA and DerivedB are subclasses of CCLayer.
The hierarchy is DerivedA and DerivedB < CCLayer < CCNode < CCObject. They're game scenes which are visible/alive at mutually exclusive times.
DerivedA has a different static function to set up playback of music which receives a CCNode caller object as a parameter and schedules another selector (doSomethingA) to begin playback and slowly fade it in using something like:
callerNode->schedule(schedule_selector(DerivedA::doSomethingA), 0.05f);
schedule_selector is what does the C-style cast. doSomethingA does not access any of its member variables or call member functions. It accesses static members and calls other static functions such as such as
CocosDenshion::SimpleAudioEngine::sharedEngine()->setBackgroundMusicVolume(sFadeMusicVolume);
The call to doSomethingA at runtime happens in CCTimer::update.
The hack is primarily to avoid duplicating code and conform to the library's callback signature (timer/scheduler system).
It's UB.
You can even use static_cast instead of the odious C-style cast, and the cast itself is quite legal. But
[Note: although class B need not contain the original member, the
dynamic type of the object on which the pointer to member is
dereferenced must contain the original member; see 5.5. —end note ] (5.2.9 12)
"The first operand is called the object expression. If the dynamic
type of the object expression does not contain the member to which the
pointer refers, the behavior is undefined" (5.5 4)
I.e., you go undefined when you call it from an object of dynamic type DerivedB.
Now, as a dirty hacks goes, it's probably not the worst (better than the manual traversing of vtables), but is it really needed? If you don't need any dynamic data, why call it on DerivedB? Base is in the library, you cannot redefine it. Callback is librarian, too, so you have to have this typedef void (Base::*SEL_SCHEDULE)(float);, OK. But why can't you define doSomething for B and make pointer to it to couple with an instance of DerivedB? You say
doSomethingA does not access any of its member variables or call
member functions. It accesses static members and calls other static
functions
But you can do it in doSomethingB as well. Or, if your callbacks are completely uncoupled from object types, and the only reason you need a member function pointer is the conformance to the library callback signature, you can make your actual callbacks non-member plain old functions, and call them from one-line members-callback conformers like DoSomething(float dt) {ReallyDoSomething(dt);}.
I'm wondering whether this is Bad (TM)
It certainly is, unless it's an override of a virtual function declared in a common base class.
If it is, then you don't need the dodgy cast; just initialise directly from &Base::DoSomethingA.
If it isn't, then the evil C cast (which here is a reinterpret_cast in disguise) allows you to apply the pointer to a type that doesn't have that member function; calling that Frankensteinian abomination could do absolutely anything. If the function doesn't actually touch the object, then there's a good chance that you won't see any ill effects; but you're still firmly in undefined behaviour.
It is not safe in general.
You have broken the type-safety system with a C-style cast of your callback in this line:
SEL_SCHEDULE pCallback = (SEL_SCHEDULE)(&DerivedA::doSomethingA);
A member function of DerivedA should operate on an instance of a DerivedA only (or something that further derives from it). You don't have one, you have a DerivedB, but because of your C-cast, your code compiled.
If your callback function had actually tried to access a member of a DerivedA you would potentially have had serious issues (undefined behaviour).
As it is the function only prints so in this case is probably not undefined, but that doesn't mean you should do it.
One typesafe way is to use a callback that takes a Base (reference) and a float and use boost::bind or std::bind to create it.
The other simple way which will probably be your answer most of the time is to just call a virtual method of Base that takes a float.

C++ Acces class array from other class

I got my main class Game:
Game.h:
class Game{
public:
Galaxian galaxians[6][10];
};
Game.cpp:
Nothing interesting, just filling the variables of the class array
Galaxian.h:
class Galaxian{
public:
void update();
};
Galaxian.cpp:
Here is my problem: I want to access the galaxians array from the Game class, but I have no idea how! When I try game::galaxians I get the error "A nonstatic member reference must be relative to a specific object"
What I am trying to accomplish is that I can loop trough that array and change a value of each key in it.
How can I do that?
This is because the galaxians member is an instance member, not a class (i.e. not a static) member. You should either (1) make an instance of Game available at the point where you need to access galaxians, or (2) make galaxians a static member.
If you decide on the first way, consider making Game a singleton; if you decide on the second way, do not forget to define your galaxians array in a cpp file, in addition to declaring it static in the header file.
Non-static members are bound to an instance of a class, not to the class itself. This is general OO, not specific to C++. So you either bind the access to an object, or the member to the class:
Game g; //create an object of the class
g.galaxians; //access the member through the object
or
class Game{
public:
static Galaxian galaxians[6][10]; //bind the member to the class
};
//...
Game::galaxians; //access it through the class
Which one you choose depends on your logic.
You need to access an instance of Game:
Game g;
g.galaxians[3][4] = ....;

Inheritance - initialization problem

I have a c++ class derived from a base class in a framework.
The derived class doesn't have any data members because I need it to be freely convertible into a base class and back - the framework is responsible for loading and saving the objects and I can't change it. My derived class just has functions for accessing the data.
But there are a couple of places where I need to store some temporary local variables to speed up access to data in the base class.
mydata* MyClass::getData() {
if ( !m_mydata ) { // set to NULL in the constructor
m_mydata = some_long_and complex_operation_to_get_the_data_in_the_base()
}
return m_mydata;
}
The problem is if I just access the object by casting the base class pointer returned from the framework to MyClass* the ctor for MyClass is never called and m_mydata is junk.
Is there a way of only initializing the m_mydata pointer once?
It doesn't have members and you must maintain bit-for-bit memory layout compatibility… except it does and C++ doesn't have a concept of freely-convertible.
If the existing framework allocates the base objects, you really can't derive from it. In that case, I can think of two options:
Define your own class Cached which links to Base by reference. Make the reference public and/or duplicate Base's interface without inheritance.
Use a hash table, unordered_map< Base *, mydata > mydata_cache;. This seems most appropriate to me. Use free functions to look up cache data before delegating to the Base *.
You could initialize your private variables in a separate initialization member function, so something like this:
class MyClass {
public:
init() {
if (!m_mydata) {
m_mydata = f();
}
}
};
framework_class_t *fclass = framework.classfactory.makeclass();
MyClass *myclass = (MyClass*)fclass;
myclass->init();
char *mydata = myclass->getData();
It's hard to say if this is a good idea or not without knowing what framework you're using, or seeing your code. This is just the first thing that came to mind after reading your description.
You could create a wrapper for the factory of the framework. The wrapper would have the same interface, delegate calls to the framework but it could initialize the created base class instance before returning it. Of course, this requires you to change your code to use the wrapper everywhere, but if it is possible, after that you can be sure that the initialization happens properly.
A variation on this: use RAiI by wrapping the base class instances into a custom autopointer which could do the initialization in its constructor. Again, if you manage to change the code everywhere to use the new wrapper type instead of the derived class directly, you are safe.