Can someone explain to me the (*this) pointer and demonstrate how it would be used as far as an object calling another object of the same class. What I don't understand is how you would refer to two numbers in a member function of different 2 different objects of the same variable name. For example, multiplying two numbers.
a.Multiply(b);
//....
Numbers::Numbers Multiply(Numbers auggend)
{
}
this pointer:
The member functions of every object have access to a pointer named this,which points to the object itself.When we call a member function,it comes into existence with the value of this set to the address of the object for which it was called.Using a this pointer any member function can find out the address of the object of which it is a member.It can also be used to access the data in the object it points to. Example:
void setdata(int ii)
{
i=ii; // one way to set data
this->i=ii; // another way to set data
}
this pointer stores the address of the class instance and can be used to initialise values
(*this) is a pointer to your instatniation of a class. In your example if Numbers class had a data value "value":
a.Multiply(b);
....
Numbers::Numbers Multiply(Numbers auggend)
{
return (this->value) * (auggend.value);
}
First off, your example doesn't look quite correct. I believe that should be:
Numbers Numbers::Multiply(Numbers auggend)
{
}
Anyway, with that said, this is simply a variable of type Numbers * const that points to your member variable. So from your example a.Multiply(b), this will hold the value of &a.
Let's say you had some other function that took a Numbers *:
void DoSomething(Numbers *num);
You can then call that function with this:
Numbers Numbers::Multiple(Numbers auggend)
{
DoSomething(this);
DoSomething(&auggend);
}
class A{
int num;
void foo(int num)
{
num = 10; //local variable num is set to 10
this->num = 10 ; //class member num is set to 10
}
};
Related
I have an int member named size within my blob class whose value I am attempting to change within a method. Initially, I tried...
void blob::make_union(blob parent_blob){
parent=&parent_blob;
parent_blob.size = parent_size
}
Then I tried making a function whose sole purpose was to change the size value. Its worth noting that it changes the values within the function as verified by some cout statements.
int blob::change_size(int dat_size){
size=size+dat_size;
return this.size;
}
after making the new method change my other method
'void blob::make_union(blob parent_blob){
parent=&parent_blob;
int temp = size;
parent_blob.size = parent_blob.change_size(temp);
}'
still no dice. The following within main function does work.
if (charmatrix[m-1][n-1]==charmatrix[m][n]){
blobmatrix[m][n].make_union(blobmatrix[m-1][n-1]);
blobmatrix[m-1][n-1].size=blobmatrix[m-1][n-1].size + blobmatrix[m][n].size;
What am I doing wrong?
You are passing your blob class by value: you are making a copy of your blob object, and that is what the function change_size is working with.
void increment_number(int i) { ++i; }
void increment_number_ref(int& i) { ++i; }
int main()
{
int n = 6;
// This takes a copy of the number, and increments that number, not the one passed in!
increment_number(n);
// n == 6
// This passed our object by reference. No copy is made, so the function works with the correct object.
increment_number_ref(n);
// n == 7
return 0;
}
You need to pass your blob by reference (or as a pointer) if you wish to modify that object's value: see above.
In languages that have pass by reference and pass by value - if you have a situation where you make a change, and then suddenly the change is 'gone', you're almost certainly passing a copy vs a reference.
Try changing the prototype to pass in the blob by reference.
Having some concerns about the functionality of the member reference and pointer operators..
Take the following example:
struct ID{
uint8_t index;
bool active;
}
struct Square{
struct ID shortID;
struct BUDDY *bud;
uint8_t x;
uint8_t y;
};
And then I later return a pointer to a square..
My question is: Can I then modify members of ID and have the changes reflected in the nested struct?
void function1()
{
Square *someSquare = GetSquare(1);
someSquare->shortID.index = 89; // Is this now reflected everywhere? OR was the shortID struct only modified in the scope of this funciton..
}
void function2()
{
Square *someSquare = GetSquare(1);
if ( someSquare->shortID.index != 89 )
{
// Dang...
}
}
Thanks!
EDIT:
Thanks for the concise answers, yes the GetSquare function returns a pointer to the specified index of an array of squares. Like so:
Square* GetSquare( uint8_t index )
{
return &squares[index];
}
So the instance should be the same every time, as the "squares" array is allocated once on object creation. So thank you for your insight my problem must be elsewhere in my code :)
yes because someSquare is a Square*
the -> operator is like a (*varname). .
So it is the content of the pointer and you get the type Square.
Then you can just modify the variable with . , because its a struct and all variables are public not like it could be in classes.
The Changes you made in function1 can be seen in function2 if the GetSquare returns the same object that could be the case if your GetSquare looks like this.
Square * GetSquare(int i)
{
static Square * pSquare = 0;
if (pSquare)
pSquare = malloc(sizeof(static Square));
return pSquare;
}
or for global variables like this
static Square pSquare ;
Square * GetSquare(int i)
{
return &pSquare;
}
If the Square pointer in function1 points to the same Square as the Square pointer in function2 then yes, you will see the value set in function1 in function2 (provided the functions are called in that sequence).
If the pointers point to different instances you will not see the value though.
As pointed out by juanchopanza, it all depends on what your GetSquare function does. Please post the definition of that function.
Its going to be in the scope because you are not using any form of global instance. I don't know what getSquare actually does, but I assume it instantiates the Square class and returns the instance...
Accessing someSquare->someID.index is just like accessing someSquare->x - in both cases it modifies the object pointed to by someSquare (in the first case it's modifying a sub-object).
Yes , if the GetSquare(1) returns the same instance, then the change should be reflected in function2() also.
If you want to be sure that the instance returned is same , try to print the value of pointer someSquare by this statement:
printf("Value of pointer: %p \n",someSquare);
If this value is same that it means they are same instances and the change should be reflected in function2().
Also GetSquare should be a global function outside of any class, or static function. If it is instance function, then it will access different arrays of class "Square" for different class objects.
Other than that, I could not give another opinion based on code available.
I have been reading an array of SRD objects from a binary file - but since this was my first time doing so, I have modified a header making all its members public as I wasn't sure what would be going on. I have completed my assignment, all that is left is to make these members private and write methods that modify them. However, there is a problem.
For debugging purposes I put only 1 member private, and until I write all methods for it I will keep it that way. This member is simply an unsigned int C. When writing a method for returning it (getC() returns C), it is returning a value of 0000...3435973836, meaning it is not set?
So, I have an array of pointers to SRD created based on the number of objects in the binary file.
SRD *a;
...
a = new SRD[numOfRecords];
and the array is filled from the file...
for (i=0; i<numOfRecords; i++)
{
f.seekg(i * sizeof s);
f.read((char *)&a[i], sizeof s);
cout << a[i].getCC();
}
now, a[i].getCC() works when C is public, but making it private makes 000..3435...
meaning accessing it is not the problem, but it is not set in the fread from the previous for loop. I imagine I need some type of assignment operator, that sets these values, but I have no clue...
When you make the variable private, the SRD class is no longer plain old data (POD). Consequently, you have no guarantees regarding its in-memory representation, and therefore you cannot rely on f.read to work like this any longer.
I suggest that you add a read-from-stream method in your class and inside that method, read directly to the unsigned int member variable. Then, in the loop, you just call that method (passing the stream as a reference or a pointer).
EDIT, example as requested:
class SRD {
...
public:
void readFromStream(istream& f) {
f.read(&CC, sizeof CC);
}
private:
unsigned int CC;
};
Loop:
for (i=0; i<numOfRecords; i++)
{
a[i].readFromStream(f);
cout << a[i].getCC();
}
Actually, the problem was something else: the header was defined in a certain order, the first member was an array, while C was the second, and while debugging i first started with the C - and moving it from the second position to the above public one, changed the structure of the class.
so,
Class P
{
int i;
char c;
}
differs from
Class P
{
char c;
int i;
}
because the data in the binary file has a specific order, and when rearranging the order of the class defenition, a member (c) tries to access data intended for another member (i)
I have a thread-class Buffer (own made class), and many derived classes such as BufferTypeA, BufferTypeB...
Since I have to synchronize them in a certain order, I'm giving any of them an integer which represents the order to run certain task. I also have to know inside each thread Buffer which one is next to run the task, so I'm passing every BufferType a reference to an integer which all of them must share and I didn't want to make it Global.
I got lost at any point and I don't see where.
First I create all the BufferTypes from a class where I also define that shared integer as:
int currentThreadOrder;
And when creating the BufferTypes:
int position = 0;
if (NULL == bufferA) {
bufferA = new BufferTypeA(¤tThreadOrder, ++position,
waitCondition);
}
if (NULL == bufferB) {
bufferB = new BufferPos(¤tThreadOrder, ++position,
waitCondition);
}
if (NULL == bufferC) {
bufferC = new BufferRtk(¤tThreadOrder, ++position,
waitCondition);
}
Then, in BufferTypeA header:
class BufferTypeA: public Buffer {
public:
BufferTypeA(int currentThreadOrder,
int threadConnectionOrder = 0,
QWaitCondition *waitCondition = NULL);
//..
}
And in cpp file:
BufferTypeA::BufferTypeA(int currentThreadOrder, int threadConnectionOrder, QWaitCondition *waitCondition):
Buffer(currentThreadOrder, threadConnectionOrder, waitCondition) { }
Now I'll show Buffer header:
class Buffer: public QThread {
public:
Buffer(int ¤tThreadOrder,
int threadConnectionOrder = 0,
QWaitCondition *waitCondition = NULL);
//...
protected:
QWaitCondition *waitCondition;
int threadConnectionOrder;
int ¤tThreadOrder; // Shared address
}
And finally the cpp:
Buffer::Buffer(int ¤tThreadOrder, int threadConnectionOrder, QWaitCondition *waitCondition) {
this->threadConnectionOrder = threadConnectionOrder;
this->waitCondition = waitCondition;
this->currentThreadOrder = currentThreadOrder;
}
And the error I'm getting is error: uninitialized reference member Buffer::currentThreadOrder.
I'm embarrased to ask, because it's going to be a simple problem with pointers and addresses, but I can't see where the problem is, so please help.
When you create a class with a data-member that is a reference, the reference needs to be assigned a value in the constructor initializer list.
References have to be given a value when they are created, they are not pointers. They have to start with a value and that value cannot be changed (while the contents that is pointed to by that value can be changed).
Essentially you can think of a reference as an alias for an existing variable. You can't give a friend a nickname if you don't have a friend :)
RESPONSE TO COMMENT:
You don't "share a reference" between objects. Each object will have its own reference to the same variable. When you "pass by reference" you are telling the compiler that you want the variable in your function to actually be the variable in your outer scope, rather than creating a new variable by value. This means that you only have one variable at one memory location. The reference is just memory in some other place that forwards you to that same memory location.
Think of this as call forwarding... I can have 15 phone numbers in 15 different countries. I can set them all up to forward calls to my cell in the US. So, people are calling me no matter which number they call.
Each of your classes just has another reference to forward the "phone calls" or variable reads/writes to that same memory location. So, you're not sharing a reference between classes, you're making sure that each class HAS a reference to the same underlying memory location.
Back to the metaphore, each class won't have the same phone, but each class' phone will forward to the same number (variable) none-the-less which lets them all set/get the same value in the end.
RESPONSE II:
Here's a simple example to get your head going, it's pretty easy to apply to your classes. I didn't compile it but it should work minus a typo or two possibly.
class A
{
public:
A(int& shared) : m_shared(shared)
{
//No actions needed, initializer list initializes
//reference above. We'll just increment the variable
//so you can see it's shared in main.
m_shared += 7;
}
void DoSomethingWithIt()
{
//Will always reflect value in main no matter which object
//we are talking about.
std::cout << m_shared << std::endl;
}
private:
//Reference variable, must be initialized in
//initializer list of constructor or you'll get the same
//compiler error again.
int& m_shared;
};
int main()
{
int my_shared_integer = 0;
//Create two A instances that share my_shared_integer.
//Both A's will initialize their internal reference to
//my_shared_integer as they will take it into their
//constructors "by reference" (see & in constructor
//signature) and save it in their initializer list.
A myFirstA(my_shared_integer);
A mySecondA(my_shared_integer);
//Prints 14 as both A's incremented it by 7 in constructors.
std::cout << my_shared_integer << std::endl;
}
you pass a pointer int* as 1st argument to BufferTypeA, which expects and int, while you said in your question you meant to use a int&. To do this, the ctor of BufferTypeA should take a int& and initialise it in an initialisation list (i.e. not within the { } part of the ctor) like
class BufferType {
int &Ref;
public:
BufferTypeA(int& ref) : Ref(ref) { /* ... */ }
};
and in your construction of BufferA you must not pass an address, but the reference, i.e.
int counter;
Buffer = new BufferType(counter);
You want code like this:
Buffer::Buffer(
int ¤tThreadOrder0,
const int threadConnectionOrder0,
QWaitCondition *const waitCondition0
) :
threadConnectionOrder(threadConnectionOrder0),
waitCondition(waitCondition0),
currentThreadOrder(currentThreadOrder0)
{}
The reason is related to the reason you cannot write
const double pi;
pi = 3.14;
but can write
const double pi = 3.14;
A reference is typically implemented as a constant pointer, to which one cannot assign an address after one has initialized the pointer. Your version of the code assigns, as in the first pi example. My version of the code initializes, as in the second pi example.
I have a variable, which is a member of one of my classes, that another is in need of, but I'm not sure how to effectively pass the value between them without using a global variable, which is something I'd like to avoid if at all possible. I know I could create an object, but that would invoke the constructor of the originating class which would execute a number of functions and write the needless results to memory, which would be wasteful of system resources.
Is there an easy way to pass this value between the two functions?
Update: The class that is in need of the variable, called no_of_existing_devices. The purpose of class Initialise is to open up a file and count the number of lines of test it contains, and place that number in the variable int no_of_existing_devices, which is then used by the Device::Device() to create an object for each
class Device
{
public:
void view_attribute_list();
void set_attribute();
Device();
};
Device::Device()
{
for (int count = 0; count < no_of_existing_devices; count ++)
{
// Create an object for each iteration, up to a maximum of no_of_existing_devices
}
}
The class of which this variable is a member
class Initialise
{
public:
int no_of_existing_devices;
bool initialisation;
string existing_device_list[100];
void initialise_existing_devices();
Initialise();
};
Initialise::Initialise()
{
no_of_existing_devices = 0;
}
void Initialise::initialise_existing_devices()
{
string line;
ifstream DeviceList;
DeviceList.open("devices/device_list");
while (true)
{
getline(DeviceList, line, '\n');
if (DeviceList.eof())
{
break;
}
++ no_of_existing_devices;
}
DeviceList.close();
DeviceList.open("devices/device_list");
for (int i = 0; i < no_of_existing_devices; i ++)
{
getline(DeviceList, line, '\n');
existing_device_list[i] = line;
}
Device existing_devices[no_of_existing_devices];
!initialisation; // Existing devices are now initialised
}
Okay, from what I understand:
You don't want to have a global
You don't want to have a static
You don't want to introduce a dependency between Device and Initialise
There is one other option, assuming something owns Device and Initialise, move the no_of_existing_devices up to there, then construct both Device and Initialise with a reference to this variable...
In a similar circumstance I was just passing the pointer to the member --- I had to invoke a member function then, so it was a pointer to the member function, http://www.parashift.com/c++-faq-lite/pointers-to-members.html
It's a bit messy, but it works :-).
If the variable in the originating class can hold a value without an instance of the class I would assume that the variable is static. If not create a public static member of the class. And use it in the target class.
Something like:
// .h file
class A
{
public:
static int a;
}
// .cpp file
int A::a = 123;
// .cpp file of class B
void B::foo()
{
cout << A::a;
}
If it is a class attribute (internal variable), then you can obtain a reference through a get method. Otherwise, you can use the friend keyword on the class you want to access the attribtue from the other For example, if you declare friend class B; on class A, the attributes of the class B will be accessible on the class A.
I suggest you use the first method in order to maintain your code OO pure ;)
Edit: of course, if you access through a reference there are no resources wasted :)
Edit 2: use a static method on Initialise class that returns the no_of_existing_devices and call Initialise::NoOfExistingDevices() on the Device class. If you want to resources use a pointer like this:
public static int* Initialise::NoOfExistingDevices() {
return &no_of_existing_devices;
}
By the way, I advise you to turn the variable private.