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] = ....;
Related
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)
I have just started to work with multiple objects/classes and I am having a hard time figuring out how to implement the data structure properly
Assuming I have a base class
class control
{
protected:
char* location
/* node** adjacency_list; This doesn't work */
};
and two different derived classes
class carA:public control
{
};
class carB:public control
{
};
and a node class.
My problem starts when I try to implement a 2D-ish structure like an array of linear linked list (graph) based on location in which the adjacency_list needs to point to the right memory space and must be available to all objects.
If I initialize the adjacency_list pointer to NULL at the base
class constructor, with every derived class object it will be set to
NULL again.
If I create the array in the base class constructor, it will create a
new array for every derived class object.
I tried to find a way with using the copy constructor of the base class in the derived class initialization list, but I couldn't justify/visualize a way that works.
So apart from declaring it globally, what/where is a simple, sensible way to declare this pointer?
I understand this might be extremely trivial, but I just can't see it at the moment.
In C++, what happens when I have the following
class House
{
public:
House();
~House();
private:
int* m_peopleInside;
friend class Room;
};
and then in the constructor of House this is set
m_peopleInside = new int[5];
m_peopleInside[4] = 2;
and
class Room
{
public:
Room();
~Room();
Update();
private:
int* m_peopleInside;
};
Then in the Room.Update() I use m_peopleInside something like this.
&m_peopleInside[4];
It's my understanding that the friend class will allow the Room class to access private members of the House class. So which m_peopleInside would be used?
I should add that in this case, m_peopleInside is being used as an array.
It's an instance variable. So it needs an instance to act on. If no instance is provided, then it is the same as this->m_peopleInside, which means it refers to the instance on which the function was called. So, for example, if this is your function:
void Room::Update() {
// these two are the same, they null the member of the Room object
m_peopleInside = nullptr;
this->m_peopleInside = nullptr;
House h;
// should be pretty obvious what this does
h.m_peopleInside = nullptr;
}
It's my understanding that the friend class will allow the Room class to access private members of the House class.
That is correct.
So which m_peopleInside would be used?
To access the m_peopleInside member of a House object, you will need an object or pointer of type House.
In Room::update(), if you simply use m_peopleInside, it will be member variable of Room, not House.
When you use "m_peopleInside" inside "Room.Update()" you will definitely use the data member of "Room". Your understanding of "friend" classes is not so correct. To make it clear, suppose that you have an object "x" from the class "House" in one of the methods of the class "Room', like "Update()" for example. Then, the following code is correct in this method:
cout << x.m_peopleInside;
Although "m_peopleInside" is private in "House", it is accessible from Room's methods, because the class "House" declares that "Room" is a friend of his.
In python we may use self keyword to declare class variables within a member function of the class which can be subsequently used by other member functions of the class.
How to do such a thing in C++.
Python Code:
class abc():
{
def __init__(self):
self.help='Mike' #self.help is the class variable and can be used in other methods
def helpf():
morehelp=self.help+' Bike'
}
C++ code:
class abc
{
public:
abc();
public:
void helpf(void);
};
abc::abc()
{
string help="Mike";
}
void abc::helpf()
{
string morehelp=this->helpf+" Bike";// this keyword sounded like the one but...
}
There is no way to do such thing in C++.
You should declare members in class, not in functions.
You cannot declare class members inside functions in C++. You have to declare them outside functions, like in JAVA
class abc
{
public:
int publicInt; // This is a public class variable, and can be accesed from outside the class
int abc();
private:
float privateFloat; // This is private class variable, and can be accesed only from inside the class and from friend functions
void helpf(void);
};
that is not possible. Declaring variables inside a member function are local to that member function. If you want to use variables in your member function you have to declare class variables.
This works in Python because Python allows you to add a attribute to an object from anywhere simply by assigning to it. It attaches to that object, rather than the object's class. In keeping with Python's dynamic language philosophy, and particularly with its lack of variable declarations, all of this - including the decision about which attributes do or don't exist - happens at run time.
C++'s explicitly does not have a concept of one particular object having an attribute - all member variables are associated with the class, even if they take independent values on each instance. The set of all possible member variables, and which types they hold, is shared class-wide and set in stone at compile time. Because of this, what you're asking for basically doesn't make sense in C++.
I have a class that should have a class of the same type as its member.
My declaration is the following:
class clsNode
{
private:
clsNode m_Mother;
public:
void setMother(const clsNode &uNode, int index);
};
C++ tells me "The object shows a type qualifier that is not compatible with the member function.
I don't know where I went wrong.
The reason is that the type of the member m_Mother has incomplete type at the point it is declared.
If you think about it. If it would have worked, you would create an object with an object inside with the same type, which in turn always have an object of the same type inside (and so on). The object would in a sense have infinite size.
One solution is to keep a pointer to the parent class instead.
class clsNode
{
private:
clsNode* m_Mother;
public:
void setMother(clsNode* uNode){ m_Mother=uNode; }
};
If you would like to have all parents always be alive during the lifetime of their children, you could use a shared pointer instead of a raw pointer.
class clsNode
{
private:
std::shared_ptr<clsNode> m_Mother;
public:
void setMother(std::shared_ptr<clsNode> uNode){ m_Mother=uNode; }
};
If you go with this solution you would originally create your objects with make_shared
You can't have a member of the same type inside the class. The compiler tries to calculate the size of the object and sort of "gets into a loop." You can get around that by using indirection. For example, you can store the pointer to the mother node.
class clsNode
{
private:
clsNode* m_Mother;
public:
void setMother(const clsNode &uNode, int index);
};
When you have a member of a class type (directly not a pointer), the instance of your mother class contains physically the contained instance.
In this case, the compiler can't find the size of the clsNode class as there's a cycle. It should contain a clsNode, which should contain a clsNode, and so forth.