still working at C++, but this came up in my book and I don't understand what it's for:
MyClass * FunctionTwo (MyClass *testClass) {
return 0;
}
My question is what is the signifigance of the first indirection operator
(MyClass *[<- this one] FunctionTwo(MyClass *testClass))?
I tried making a function like it in codeblocks, with and without the first * and I didn't see any difference in the way it ran or it's output:
int *testFunc(int *in) {
cout << in << endl;
cout << *in << endl;
return 0;
}
int testFuncTwo(int *in) {
cout << in << endl;
cout << *in << endl;
return 0;
}
I couldn't find anywhere that explained about it in my book.
Thanks,
Karl
The MyClass * means that this function returns a pointer to a MyClass instance.
Since the code is actually returning 0 (or NULL) this means that any caller to this function gets back a NULL pointer to a MyClass object.
I think the following are better examples:
int *testFunc(int *in) {
cout << "This is the pointer to in " << in << endl;
cout << "This is the value of in " << *in << endl;
return in;
}
int testFuncTwo(int *in) {
cout << "This is the pointer to in " << in << endl;
cout << "This is the value of in " << *in << endl;
return *in;
}
void test() {
int a = 1;
cout << "a = " << a;
int output = *testFunc(&a); // pass in the address of a
cout << "testFunc(a) returned " << output;
output = testFuncTwo(&a); // pass in the address of a
cout << "testFuncTwo(a) returned " << output;
}
Apologies, but I've not done C++ in years but the syntax may be a little off.
The general format for a function that takes a single value and returns a single value in C++ is:
return_type function name ( parameter_type parameter_name )
In your case, return_type is MyClass *, which means "pointer to MyClass"
In addition, in your case, parameter_type is also MyClass *.
In other words, your code could be rewritten as:
typedef MyClass *PointerToMyClass;
PointerToMyClass FunctionTwo (PointerToMyClass testClass)
{
return 0;
}
Does that look more familiar?
Given the nature of the question, I'm going to provide a somewhat crude answer.
A pointer points to something:
int x = 123; // x is a memory location (lvalue)
int* y = &x; // y points to x
int** z = &y; // z points to y
In the above code, z points to y which points to x which stores an integral, 123.
x->y->z[123] (this is not code, it's a
text diagram)
We can make y point to another integer if we want or NULL to make it point to nothing, and we can make z point to another pointer to an integer if we want or NULL to make it point to nothing.
So why do we need pointers which point to other things? Here's an example: let's say you have a simple game engine and you want to store a list of players in the game. Perhaps at some point in the game, a player can die by having a kill function called on that player:
void kill(Player* p);
We want to pass a pointer to the player, because we want to kill the original player. Had we done this instead:
void kill(Player p);
We would not kill the original player, but a copy of him. That wouldn't do anything to the original player.
Pointers can be assigned/initialized with a NULL value (either NULL or 0) which means that the pointer will not point to anything (or cease to point to anything if it was pointing to something before).
Later you will learn about references which are similar to pointers except a pointer can change what it points to during its lifetime. A reference cannot, and avoids the need to explicitly dereference the pointer to access the pointee (what it's pointing to).
Note: I kind of skirted around your original question, but the sample code you provided has no inherent meaningful behavior. To try to understand that example without first understanding pointers in a general sense is working backwards IMHO, and you'd be better to learn this general theory first.
If you had something like int * Function() this would return a pointer to an integer. MyClass * just means that the function is going to return a pointer to an object of type MyClass. In c++ user defined objects are treated as first-class-objects, so once you create your own objects they can be passed as a parameter, returned from a subroutine, or assigned into a variable just like the standard types.
In the code blocks you posted there will be no difference in the output to the console because the thing you have changed is the type that the function returns (which is not used), the contents of the functions are identical.
When you define:
int *testFunc(int *in)
You are defining a function which returns a pointer to an int variable.
int testFuncTwo(int *in)
Returns just an int variable.
Zero in this case is undergoing an implicit cast - the first function returns (int*) 0, the second just 0. You can see this implicit cast in action if you change the prototype of your example function from returning a MyClass* to just returning a MyClass - if there's no operator int method in MyClass, you'll get a nice error.
Related
int a = 1;
int &b = a;
Here, the reference b has a type int, but, what is the purpose of it having a type when it is not an object? What if that type was different of that of the object it refers to?
The purpose of having typed references (i.e. pointers) is to enable type checking (which helps to catch bugs). If you were to declare a reference as a different type, you will get a type error (you can cast it, but that needs to be done explicitly).
According to Sumita Arora's book 'Computer Science with C++' The reference variables are often treated as derived data type in which it has a property of storing variable addresses.It is means of providing an alias to the existing variable.That is existing variable can be called by using this alternate names.
Suppose when we want to perform swapping of two variables using references.
// function definition to swap the values.
void swap(int &x, int &y) {
int temp;
temp = x; // save the value at address x
x = y; // put y into x
y = temp; // put x into y
return;
}
void main () {
// local variable declaration:
int a = 100;
int b = 200;
cout << "Before swap, value of a :" << a << endl;
cout << "Before swap, value of b :" << b << endl;
/* calling a function to swap the values using variable reference.*/
swap(a, b);
cout << "After swap, value of a :" << a << endl;
cout << "After swap, value of b :" << b << endl;
getch();
}
Here,swapping is performed using call by reference method and the changes will be reflected at actual parameters also.Here modification of passed parameters are done quite easily which serves one of its actual purpose.Whenever,there is a comparison with integer variable and a reference variable during swapping,the possible error might occur is type mismatch error,since address is being compared with value.Here integer references are used to identify that it could store addresses of integer variables only, which is possibly a mechanism developed to tackle type mismatch errors and make compiler identify that the given address holds an integer or the datatype specified by reference such that the program runs smoothly and performs operations.References also eliminates wild pointer cases and often provides easy-to-use interface.
As a beginner in C++, first thing I came accross for functions is that they use a copy of the argument, for example if we execute this :
void add (double x){
x=x+3;
}
int main(){
double x=2 ;
add(x) ;
}
Then x would actually be equal to 2, not 5. Later on, learning about pointers, I found the following :
void fill (int *t){
for (int j=0, j<10, j++){
t[j]=j;
}
int main(){
int* p;
p = new int[10];
fill(p);
}
Now if we print what p contains, we find that it's indeed filled by the integers. I have some trouble understanding why it does that as I feel like it should have been the same as the first function ?
Thanks.
The reason it isn't the same as the first function is because you are passing the pointer by value. This means that if you modify the actual pointer, e.g by assigning to it, then it would only be in that state inside the function. The value that the pointer points to is still the original value, which will get modified since both copied pointers point to that same original value (don't forget notation of the form a[i] is equivalent to *(a + i), which does a dereference and is modifying the pointed value, not the pointer itself).
A small example that illustrates this would be the following (not accounting for memory leaks):
#include <iostream>
int test(int* x)
{
int* y = new int{10};
x = y;
std::cout << "Inside function: " << *x << "\n";
}
int main()
{
int* t = new int{5};
std::cout << "Before function: " << *t << "\n";
test(t);
std::cout << "After function: " << *t << "\n";
}
In first example you are using ordinary variable. When passing normal variable to function, like this, the function creates its own copy of the variable (it has same value as it has when you passed it, but it was copied to different place in memory). That is standard behaviour.
In second example you are using pointer: we can say that it points to the place in memory, where values are stored. Few of the advantages of them:
1) If you want to spare memory, but need to use same value in different functions -> mostly appplies to bigger objects than double, like array in your example
2) If you need to change value of variable/array/object in different functions
But careful, in the second function you still created copy, but not of value, but pointer. So basically, the "new" pointer is different object, but it is pointing to the same place in memory, so when accessing the value (which you are doing with [j]), you are editing the same place in memory.
It is not that easy concept to grasp, especially with more dimentional arrays, but hope this helped a little. You can learn some more in tutorials or c++ docs, for example this is a good one: https://www.geeksforgeeks.org/pointers-in-c-and-c-set-1-introduction-arithmetic-and-array/
Not really sure what's going on here, I'm using Clion as my IDE which I don't believe has anything to do with this but I figured I'd add that information. My confusion comes from a function that I wrote
int Arry()
{
int Mynumbers [5] = {10};
std::cout << Mynumbers;
}
something simple. It should be assigning 5 integers the value of 10. But when I print out Mynumbers I am shown the memory address. Why is this happening, I thought that was what calling pointers was for. Thank you for your time.
Sincerely,
Nicholas
It is a bit complicated, and there are a few issues at play:
std::cout (actually, std::ostream, of which std::cout is an instance, does not have an overload of operator<< that understands plain arrays. It does have overloads that understand pointers.
In C++ (and C) an array name can be used as an expression in a place where a pointer is needed. When there is no better option, the array name will decay to a pointer. That is what makes the following legal: int a[10] = {}; int* p = a;.
The overload that takes a pointer prints it as a hexadecimal address, unless the pointer is of type char* or const char* (or wchar versions), in which case it treats it as a null terminated string.
This is what is happening here: because there isn't an operator<< overload that matches the array, it decays to the overload taking a pointer. And as it isn't a character type pointer, you see the hexadecimal address. You are seeing the equivalent of cout << &MyNumbers[0];.
Some notes:
void Arry() // use void if nothing is being returned
{
int Mynumbers[5] = {10}; // first element is 10, the rest are 0
//std::cout << Mynumbers; // will print the first address because the array decays to a pointer which is then printed
for (auto i : Mynumbers) // range-for takes note of the size of the array (no decay)
std::cout << i << '\t';
}
In C++, you can think of an array as a pointer to a memory address (this isn't strictly true, and others can explain the subtle differences). When you are calling cout on your array name, you are asking for it's contents: the memory address.
If you wish to see what's in the array, you can use a simple for loop:
for (int i = 0; i < 5; i++)
std::cout << Mynumbers[i] << " ";
The value of Mynumbers is in fact the adress of the first element in the array.
try the following:
for(int i=0; i<5;i++) {
cout << Mynumbers[i];
}
I'm researching the differences between stack and heap allocation, which has its own long list of disputes on when to use which. My question is not related to that discussion though; it is about the semantics of testing these two ideas.
Consider the following situation describing the usual ways variables are passed between functions:
void passByPtr(Node* n)
{n->value = 1;}
void passByRef(Node& n)
{n.value = 2;}
void passByValue(Node n)
{n.value = 3;}
void indirectionTesting()
{
Node* heapNode = new Node();
Node stackNode= Node();
// Initialize values
heapNode->value = 0, stackNode.value = 0;
cout << heapNode->value << ", "<< stackNode.value << endl;
// Passed ptr by ptr (pass by reference)
passByPtr(heapNode);
passByPtr(&stackNode);
cout << heapNode->value << ", "<< stackNode.value << endl;
// Pass by reference
passByRef(*heapNode);
passByRef(stackNode);
cout << heapNode->value << ", "<< stackNode.value << endl;
// Pass by value
passByValue(*heapNode);
passByValue(stackNode);
cout << heapNode->value << ", "<< stackNode.value << endl;
delete heapNode;
}
int main()
{
indirectionTesting();
/* Output
0, 0
1, 1
2, 2
2, 2 */
return 0;
}
These are the two ways I was taught how to handle variable passing between methods. There are a lot of arguments for and against here. I read all of them.
But I had an idea... you see, I'd prefer for the caller to be able to easily out whether or not a function is conceptually pass-by-value or pass-by-reference. (i.e. (func(&var)) In my humble opinion, the transparency supplements the idea of encapsulation.
But there's a problem. The 'new' keyword always returns a pointer. As you can tell from the above example, if you use a mix of stack-allocated and heap-allocated variables in your program, it can quickly become confusing how to pass them by reference.
So after playing around with reference types, now consider this portion of code:
void passByPtr(Node* n)
{n->value = 1;}
void passByRef(Node& n)
{n.value = 2;}
void passByValue(Node n)
{n.value = 3;}
void indirectionTesting()
{
Node& heapNode = *new Node();
Node stackNode= Node();
// Initialize values
heapNode.value = 0, stackNode.value = 0;
cout << heapNode.value << ", "<< stackNode.value << endl;
// Passed ptr by ptr (pass by reference)
passByPtr(&heapNode);
passByPtr(&stackNode);
cout << heapNode.value << ", "<< stackNode.value << endl;
// Pass by reference
passByRef(heapNode);
passByRef(stackNode);
cout << heapNode.value << ", "<< stackNode.value << endl;
// Pass by value
passByValue(heapNode);
passByValue(stackNode);
cout << heapNode.value << ", "<< stackNode.value << endl;
delete &heapNode;
}
int main()
{
indirectionTesting();
/* Output
0, 0
1, 1
2, 2
2, 2 */
return 0;
}
Ignoring how strange the heap-allocated variable instantiation looks, does anyone see anything wrong with this?
They both function exactly the same. The way I see it, choosing to follow this type of convention allows me to freely choose whether to allocate on the stack or heap whilst allowing me to use the same calling convention for all of my functions, again regardless whether or not they are heap or stack allocated. I don't personally see any validity in the argument that "I will confuse which variables were allocated on the stack and which on the heap," but share your opinion if you think I'm wrong.
Does anyone see anything else wrong with this approach?
I recommend passing by reference to functions. A reference indicates that the object exists.
When passing by pointer, the receiving function doesn't know if the pointer is valid or not and must test the pointer.
The passing by reference is a safer and more robust style.
If you really want to do this:
Have the caller determine whether the parameter is by ref, value or ptr
Be able to swap object types between stack and heap
Then I think you might be able to do something along these lines:
auto my_node = make_object<Node>(); // factory hides value/heap creation
Then you'd make every object created be wrapped by a class which has pointer semantics. So if my_node is on the heap, it's wrapped so everything uses my_node-> or *my_node (even though the wrapper is just storing it as a member variable).
Since you are now working with wrapped types, a function might have a signature like:
value<Node> my_function( parameter<Node> );
I haven't thought through the details of how these classes might operate but I was thinking something along the lines of:
parameter can only be constructed from a reference, value or ptr. So the caller then specifies which of these it wants and some mechanics under the covers deal with getting the parameter through in the correct form.
// in the function with the my_node object
auto ret = my_function( pass_by_reference(my_node) );
I'm sure there will be some tricky bits in the implementation but on a surface level I think something along these lines would let you overload the make_object so different object types are associated with heap/stack as desired.
You wouldn't be able to work with anything like it is a reference - you'd have to deal with pointer syntax because its the lowest common denominator. However you could retain the semantics of something being a reference or a pointer (can be made null or rebound) or a value (on the stack).
Clearly there would be some inefficiency somewhere because the generic 'parameter' type would need to be able to operate in 3 different 'modes'.
But you know - you are trying to make the language do something it wasn't designed to. However the strength of C++ is that where theres a will, theres a way.
Maybe someone will tell me why the above will not work. I'd be happy to hear that but on a cursory consideration I think it could be made to work.
pass by pointer as last resort.
the best option - pass by reference as much as possible. references prevents you passing null pointers and dangling pointers. it also prevent you doing the bad bad practice of passing null as "no valid input".
there are also places you MUST pass by const reference, like in any function that gets temporary object as parameter, or copy constructors
also, every object that weight more than sizeof(void*) can benefit by passing it by reference - the reference pass will cost less byte-copying thus a faster program. pass heavy objects as references if they need to change and as const references if they do not.
if you can't pass by reference , try pass by smart pointers - std::weak_ptr and std::shared_ptr (you cant pass std::unique_ptr, or at least, you shouldn't).
you pass by raw pointer when :
you can't pass by reference, for instance like passing this
null is a legit argument
C-API's
you don't pass either by pointer nor reference if:
you do want your object to be copied
there is no performance improvement. for example, I pass a character and I don't want it to be changed, yet , passing it as const reference makes the program slower (references are usually implemented behind the scenes as pointers, and they weight many times heavier than single character)
few more things:
you CAN catch a new result with reference, just dereference it first:
int& x = *new int(4)
don't use new/delete unless you're dealing with performance. use smart pointers instead (std::shared_ptr,std::unique_ptr).
even if you do have a pointer as variable (for example, if you imlement linked list or singleton and you use raw pointers) , you can still and should return it as reference:
T& T::getInstance(){
if (!m_Instance){
m_Instance = new T();
}
return *m_Instance;
}
and again , the above code CAN AND SHOULD be used with smart pointers
I was trying to access the private data members of the class. Everything was going fine until I came upon the int*. I don’t get what it is. I think it’s something that we can use to create a new memory address.
My code :
#include <iostream>
using namespace std;
class x
{
int a, b, c, d;
public:
x()
{
a = 100;
b = 200;
c = 300;
d = 400;
}
};
int main()
{
x ob;
int *y = (int *)&ob;
cout << *y << " " << y[1] << " " << y[2] << " " << y[3] << endl;
}
Can anyone help me in understanding it?
Its a c-style cast to access the memory occupied by the struct x as a set of ints.
It takes the address of ob, casts it from 'address of' (ie a pointer to) x into a pointer to int. The compiler happily assigns this cast to y, so you can manipulate it, or in this case, print out the memory blocks as ints. As the struct happens to be a group of ints anyway, it all works even though its a bit of a hack. I guess the original coder wanted to print out all 4 ints without having to specify each one in turn by variable name. Lazy.
Try using a cast to a char* (ie 1 byte at a time) and print those out. You'll be basically printing out the raw memory occupied by the struct.
A good C++ way would be to create an operator<< function that returns each variable formatted for output like this, then write cout << ob << endl; instead.