This question already has answers here:
Function argument type followed by *&
(3 answers)
Closed 9 years ago.
I was looking at manual of ACE framework and came across this declaration
int ACE_Stream<>::get (ACE_Message_Block *& mb, ACE_Time_Value * timeout = 0)
I'm not able to understand what *& stands for. I know * is for pointer and & is reference. Can any one explain what is the meaning of this declaration.
Thanks in advance
So as #NPE said *& makes changes to pointer propagate back. But to understand I just wrote down some code sharing it so that it can help others understand this correctly
#include <iostream>
using namespace std;
class DoSomething
{
public:
int n;
DoSomething(int i){
n = i;
}
virtual ~DoSomething();
};
DoSomething::~DoSomething()
{
}
int dosomething(DoSomething * a)
{
cout << "Got value from caller: (in dosomething) = " << a << endl;
a = new DoSomething(25);
return 0;
}
int dosomethingElse(DoSomething *& a)
{
cout << "Got value from caller: (in dosomethingElse) = " << a << endl;
a = new DoSomething(15);
return 0;
}
int main(int argc, char *argv[])
{
DoSomething *d = new DoSomething(10);
cout << "Pointer to DoSomething: " << d << endl;
dosomething(d);
cout << "After dosomething value of d: " << d << endl << endl;
dosomethingElse(d);
cout << "After dosomethingElse value of d: " << d << endl << endl;
delete d;
return 0;
}
So as #NPE said here is out put of this
Pointer to DoSomething: 0x955f008
Got value from caller: (in dosomething) = 0x955f008
After dosomething value of d: 0x955f008
Got value from caller: (in dosomethingElse) = 0x955f008
After dosomethingElse value of d: 0x955f028
So indeed if I create a new instance inside function it will propagate only if I use *& and not just *
Thank you to every one for the answers.
I know * is for pointer and & is reference.
Correct. So what you have here is a pointer, passed by reference.
mb is a pointer that's being passed by reference. This means that if get() were to change the value of the pointer, the change would propagate back to the caller.
Related
For the following code:
#include <memory>
#include <iostream>
#include <vector>
using namespace std;
struct pm
{
pm() : a(make_unique<vector<int>>(1, 10)){};
unique_ptr<vector<int>> a;
};
struct parms
{
parms() : a(make_unique<pm>()){};
unique_ptr<pm> a;
};
class test
{
public:
test() : p(make_unique<parms>()) {}
unique_ptr<const parms> getParms()
{
return move(p);
}
void setParms(int b)
{
p->a->a->push_back(b);
}
void pp()
{
cout << p->a->a->at(0) << "\n";
}
private:
unique_ptr<parms> p;
};
int main()
{
auto t = make_unique<test>();
t->pp();
cout << t->getParms()->a->a->at(0) << "\n";
cout << (t->getParms()==nullptr) << "\n"; ;
}
t->getParms() is a nullptr after we "cout << t->getParms()->a->a->at(0) << "\n";".
If we do the same thing for the ptr,
int main()
{
auto t = make_unique<test>();
t->setParms(5);
t->pp();
auto ptr = t->getParms();
cout << ptr->a->a->at(0) << "\n";
cout << (ptr==nullptr) << "\n"; ;
}
ptr is not a nullptr.
My question is: why cout t->getParms(), then t->getParms() is a nullptr but prt is not? Is it because of the life scope of unique_ptr? Or the temporary rvalue? What's the reason behind this behavior?
Your method getParams() transfers ownership to the caller.
unique_ptr<const parms> getParms()
{
return move(p);
}
Member is moved to the return value and now the caller owns the pointee. You are not storing the returned value here:
cout << t->getParms()->a->a->at(0) << "\n";
Though, even if you did, t does not own the param anymore, hence when you ask t again:
cout << (t->getParms()==nullptr) << "\n"; ;
It doesnt know about the param anymore.
In the second example you transfer ownership from t to ptr:
auto ptr = t->getParms();
Now ptr owns the param. And you can inspect the pointer or the value as often as you like:
cout << ptr->a->a->at(0) << "\n";
cout << (ptr==nullptr) << "\n"; ;
There is no transfer of ownership in those two lines.
What's the reason behind this behavior?
The reason, as stated above, is that getParams() transfers ownership to the caller. Thats rather uncommon for a getter method. Perhaps "stealer-method" would be a better name ;). If you don't want to give up ownership (and you are certain that the pointer is a valid one) you can simply return a reference:
const parms& getParms() const { return *p; }
My question is: why cout t->getParms(), then t->getParms() is a nullptr but prt is not?
t->getParms() transfers the ownership to the caller. This sets t->p to null. Since t->p no longer owns a pointer, there is nothing to transfer when you call t->getParms() a second time.
You never transferred ownership from ptr, so it hasn't been set to null.
Basically I'm wondering what the rules are for passing in pointers vs references to functions in C++. I couldn't find them stated anywhere. Can you pass a primitive type integer, for example, into a function expecting a pointer? Can't you only pass in pointers to methods expecting pointers?
A pointer is just a memory address and in c++ you can get the address of a variable by using the &. Here is an example
#include <iostream>
void increment(int& x)
{
++x;
}
void increment2(int* x)
{
++(*x);
}
int main()
{
int i = 1;
int * p = new int(1);
increment2(&i);
increment2(p);
std::cout << i << std::endl;
std::cout << *p << std::endl;
increment(i);
increment(*p);
std::cout << i << std::endl;
std::cout << *p << std::endl;
}
output
2
2
3
3
try it:
https://godbolt.org/z/br9APq
I have two classes, let's call them A and B
class A:
{
public:
//Some functions
A *getNewA() const;
private:
//some attributes
}
class B:
{
public:
//Some functions
private:
A &reftoA;
}
In the main code, I must generate a new A thanks to the A::getNewA() method. And this must go to B::reftoA, as written in class B.
Here is the A::getNewA() method :
A *A::getNewA()
{
A *newA = new A;
return newA;
}
OK. So now I call getNewA and want to store the results in reftoA, which is a reference to A. In a B function (which take a reference to A as parameter)
B::foo(A ¶mA)
{
reftoA = *(paramA.getNewA());
}
I thought this should have been working, but it won't.
Because when dereferencing, reftoA will always take the this object and not the new allocated object.
Let's be clearer and let's modify the functions to output the results
A * A::getNewA()
{
A *newA = new A;
std::cout << "New pointer " << newA << std::endl;
std::cout << "this pointer" << this << std::endl;
return A;
}
void B::foo(A ¶mA)
{
reftoA = *(paramA.getNewA());
std::cout << "new generated pointer " << &reftoA << std::endl;
}
Here is one of the output :
New pointer : 004FFAEC
this pointer: 0069D888
New generated pointer : 0069D888 //Expected : 004FFAEC
I can't get this "new generated pointer" to be the same than the new pointer the A::getNewA() returns after having allocated the memory. Of course, I guess there is some point with dereferencing the pointer to store it in a reference.
I know reference are used with existing object. Maybe the new object A::getNewA() should allocate memory for won't work as I expected.
I could use pointer instead reference in B::foo(), I know, but I can't
I think I am misunderstanding something about refrence and pointer, but I don't know what.
Any help greatly appreciated
The problem is that you can not reassign a reference. You can change only the value of the referenced object.
So you have to initialize the reference in the initializer list of the constructor of the class B.
Take into account that there is a typo in your code snippet
A*A::getNewA()
{
A *newA = new A;
std::cout << "New pointer " << newA << std::endl;
std::cout << "this pointer" << this << std::endl;
return A;
^^^^^^^^^
}
I think you mean
A*A::getNewA() const
^^^^^
{
A *newA = new A;
std::cout << "New pointer " << newA << std::endl;
std::cout << "this pointer" << this << std::endl;
return newA;
^^^^^^^^^^^
}
Always try to provide a verifiable complete example.
Here is a demonstrative program
#include <iostream>
class A
{
public :
//Some functions
A* getNewA() const
{
A *newA = new A;
std::cout << "New pointer " << newA << std::endl;
std::cout << "this pointer" << this << std::endl;
return newA;
}
private :
//some attributes
};
class B
{
public :
B( const A& a ) : reftoA( *a.getNewA() )
{
std::cout << "&reftoA " << &reftoA << std::endl;
}
private :
A& reftoA;
};
int main()
{
A a;
B b( a );
return 0;
}
Its output is
New pointer 0x2b392afbec20
this pointer0x7ffd287ad0af
&reftoA 0x2b392afbec20
As you can see the values of the New pointer and &reftoA are equal each other.
To make it more clear consider a very simple example
#include <iostream>
int main()
{
int x = 10;
int y = 20;
int &r = x;
r = y;
std::cout << "x = " << x << std::endl;
std::cout << "y = " << y << std::endl;
std::cout << "r = " << r << std::endl;
std::cout << std::endl;
std::cout << "&x = " << &x << std::endl;
std::cout << "&y = " << &y << std::endl;
std::cout << "&r = " << &r << std::endl;
return 0;
}
The program output is
x = 20
y = 20
r = 20
&x = 0x7ffd88ad47a8
&y = 0x7ffd88ad47ac
&r = 0x7ffd88ad47a8
This statement
r = y;
did not force the reference to refer the object y. It just reassigned the value of the referenced object x.
References have to be initialized when they are created.
Yes, you are misunderstanding something.
getNewA() is returning a pointer. it's not a smart pointer, you want to look into those and that's all I'll say on the matter.
on returning a pointer, you must keep a reference to this pointer else you will be unable to delete it and you'll get a memory leak. Thus you MUST have somewhere A* a = A::getNewA() and then later, when you no longer need it delete a;
Where you need to pass a reference to A, you can do foo(*a) which will dereference the pointer and pass a reference to the object it's pointing to.
But in summary, for all new code, smart pointers; there's no excuse to not use them.
Side note: Your code example had a few other issues; such as getNewA wasn't static; I'm going to take the code as a working example of your understanding, and not a working example.
Edit: On re-reading your example, the getNewA is intentionally non-static. I think this question is actually an XY problem (ie you're asking a question you've forced yourself into but isn't your actual problem); but I hope this addresses your misunderstanding of pointers and references.
You are not returning the pointer in the getNewA-Method
A* A::getNewA()
{
A *newA = new A;
return A; // you are returning A and not newA
}
And if you want to reassign the reference to a you can use a std::reference_wrapper
class B :
{
public :
void foo(A& paramA) {
reftoA = *(paramA.getNewA());
}
private :
std::reference_wrapper<A> reftoA;
}
This question already has answers here:
What are the differences between a pointer variable and a reference variable?
(44 answers)
Closed 7 years ago.
Can you tell me the difference between the source 1 and 2?
The book says the first one is call by address(pointer) and the second one is call by reference, but i don't exactly get those two sources.
Please explain those sources to me please, thank you in advance.
1.
#include <iostream>
using namespace std;
void absolute(int *a);
void main()
{
int a = -10;
cout << "Value a before calling the main function = " << a << endl;
absolute(&a);
cout << "Value a after calling the main function = " << a << endl;
}
void absolute(int *a)
{
if (*a < 0)
*a = -*a;
}
2.
#include <iostream>
using namespace std;
void absolute(int &a);
void main()
{
int a = -10;
cout << "Value a before calling the main function" << a << endl;
absolute(a);
cout << "Value a after calling the main function" << a << endl;
}
void absolute(int &a)
{
if (a < 0)
a = -a;
}
In terms of what happens at the CPU level, pointers and references are exactly the same. The difference lies in the compiler, it won't let you do a delete on a reference (and there's less typing)
So in your code both functions do the same thing.
This question already has answers here:
What is object slicing?
(18 answers)
Closed 9 years ago.
I have the following setup:
main.cpp:
int main()
{
vector <Tour> tourList;
Tour* tour_ptr;
for (unsigned int i = 0; i < tourList.size(); i++)
{
tour_ptr = &tourList[i];
tour_ptr->display();
}
}
Tour.h:
class Tour
{
public:
virtual void display();
};
Tour.cpp:
void Tour::display()
{
cout << "Tour ID: " << getID() << "\n";
cout << "Description: " << getdescription() << "\n";
cout << "Tour Fee: $" << getfee() << "\n";
cout << "Total Bookings: " << getbookings() << "\n\n";
}
GuidedTour.h:
class GuidedTour : public Tour
{
public:
void display();
};
GuidedTour.cpp:
void GuidedTour::display()
{
Tour::display();
cout << "Max Tour Group Size: " << getMaxTourists() << "\n";
cout << "Tour Guide: " << getGuideName() << "\n";
cout << "Tour Date: " << getTourDate() << "\n\n";
}
GuidedTour inherits from the Tour class, and I've specified the display() function as virtual in the base Tour class, but for some reason, the GuidedTour display() function never gets called, only the base function gets called every time. What am I doing wrong?
Your code actually doesn't print anything as the std::vector would initially be empty. Other than that, your problem is caused by object slicing (I'm assuming that you are push_back()ing GuidedTours into the vector).
When object slicing takes place, you are storing only the Tour part of your GuidedTour object(s), and that's the reason why you are seeing the output of Tour::display().
To solve your problem, you need to store the objects polymorphically, by using (smart) pointers and dynamically-allocating your objects.
int main()
{
vector <std::unique_ptr<Tour>> tourList;
for(...) {
tourList.push_back(std::make_unique<GuidedTour>(/* constructor parameters */));
...
tourList.push_back(std::make_unique<Tour>(/* constructor parameters */));
}
for (unsigned int i = 0; i < tourList.size(); i++)
{
tourList[i]->display();
}
}
Notice that I am using std::unique_ptr/std::make_unique and not raw newed pointers. Using them would greatly ease you of the problem of manually managing and deleteing your objects, which sometimes[understatement] are the cause of bugs and undefined behavior.
Note that some people might suggest you to use boost::ptr_vector or something similar. Listen to them, especially if they give you arguments on why they are better than the alternatives.
Your problem has nothing to do with your classes, rather how you are creating the object. Each element in the tourList vector is a tour, and nothing at compile time or runtime is there to determine that they are GuidedTours. In effect, GuidedTour is never called, because I don't see a GuidedTour object in your main anywhere.
I am agree with "It'sPete". because you haven't used the GuidedTour class. It will work if you use the following method.
int main()
{
vector <GuidedTour> tourList;
Tour* tour_ptr;
for (unsigned int i = 0; i < tourList.size(); i++)
{
tour_ptr = &tourList[i];
tour_ptr->display();
}
}