C++ Question Help with pointers

Hlynkacg

Aspiring rocket scientist
Addon Developer
Tutorial Publisher
Donator
Joined
Dec 27, 2010
Messages
1,870
Reaction score
3
Points
0
Location
San Diego
Once again I apologize for the noobish question, but I haven't really worked with pointers much and I'd like some help.

I want pass a variable to a class instance on initialization and then have it monitor the value of that variable without having to pass it again each time step. I know that this is possible through pointers but am having a bit of trouble with the implementation.

"double *value" is a member of my "cockpit gauge" class whos' initializer looks like this...

Code:
Gauge1::Gauge1(VESSEL3 * v, double *val)
{
    value = &val;

    //...plus other stuff getting initialized 
}

My understanding from reading of the c++ documentation was that If I initialized the class in my vessel's code as follows...

Code:
pressuregauge = new Gauge1(this, &press_kpa); // "pressuregauge" and "press_kpa" are both members of my vessel class

that "Gauge1.value" and "MyVessel.press_kpa" would be effectively linked but in practice this does not seem to be the case as changes in the value of "press_kpa" on the vessel side are not being reflected by "value" on the Gauge side.

Any help would be greatly appreciated.
 

Blake

Addon Developer
Addon Developer
Joined
Mar 9, 2009
Messages
233
Reaction score
120
Points
58
Location
Lehi, Utah
Quick off-the-cuff answer:

Code:
Gauge1::Gauge1(VESSEL3 * v, double *val)
{
    value = &val;

    //...plus other stuff getting initialized 
}

should be:

Code:
Gauge1::Gauge1(VESSEL3 * v, double *val)
{
    value = val;

    //...plus other stuff getting initialized 
}

You are already passing in a 'pointer to double', you don't need to then take the address of that pointer.
 

RisingFury

OBSP developer
Addon Developer
Joined
Aug 15, 2008
Messages
6,427
Reaction score
492
Points
173
Location
Among bits and Bytes...
Once again I apologize for the noobish question, but I haven't really worked with pointers much and I'd like some help.

I want pass a variable to a class instance on initialization and then have it monitor the value of that variable without having to pass it again each time step. I know that this is possible through pointers but am having a bit of trouble with the implementation.

"double *value" is a member of my "cockpit gauge" class whos' initializer looks like this...

Code:
Gauge1::Gauge1(VESSEL3 * v, double *val)
{
    value = &val;

    //...plus other stuff getting initialized 
}

My understanding from reading of the c++ documentation was that If I initialized the class in my vessel's code as follows...

Code:
pressuregauge = new Gauge1(this, &press_kpa); // "pressuregauge" and "press_kpa" are both members of my vessel class

that "Gauge1.value" and "MyVessel.press_kpa" would be effectively linked but in practice this does not seem to be the case as changes in the value of "press_kpa" on the vessel side are not being reflected by "value" on the Gauge side.

Any help would be greatly appreciated.

Pointers work like this: When you pass something like this:

Code:
void MyFunction(double *Variable)
{
      ...
}

And then you call the function like this:

Code:
double Pressure = 10;

MyFunction(&Pressure);

What gets passed to the function is not the value 10, but the address in memory where the value is written. The & operator means "The address of", so what you're passing to MyFunction is "The address of Pressure".

Once inside MyFunction, you can access the value by using the * operator. * operator is "What's the value hiding behind this address" operator. So if you do (*Variable), it'll turn the address number into the actual value.

The way you'd implement it is like this:

Code:
Gague1 *PressureGague = new Gague1(this, &PressureKPA);

This passes the address of PressureKPA variable to the newly created object of Gague1 class.

Inside the class, you'd want to save not the value, but the address of it, so the class would be defined this way:

Code:
class Gague1
{
public:
      Gague1(VESSEL3 *MyVessel, double *PressureKPA);
      ~Gague1();

      void DoPressureCheck();

private:
      double *PressureKPA;
};

And the definition would then be:

Code:
Gague1::Gague1(Vessel3 *MyVessel, double *PressureKPA)
{
      this->PressureKPA = PressureKPA;

      ...
}

There are two variables here. One is local, defied by the constructor, the other belongs to the object. this-> refers to the object's variable. The statement saves the address of where the value is held.

To access the value at any point, you can do this:

Code:
void Gague1::DoPressureCheck()
{
      double CurrentPressureKPA = (*PressureKPA);
}

The * operator then says "What's the value hidden behind the address held in PressureKPA?". This time I don't need the keyword this->, because there is no local variable to confuse the name.
 

Hlynkacg

Aspiring rocket scientist
Addon Developer
Tutorial Publisher
Donator
Joined
Dec 27, 2010
Messages
1,870
Reaction score
3
Points
0
Location
San Diego
@RisingFury
Thank you, it looks like I set everything up correctly but using...

Code:
current_value = (*value)

...to access the value contained in the pointer as opposed to the pointer itself was the critical step that I had missed.

ETA:
It works! :cheers:
 
Last edited:

Bibi Uncle

50% Orbinaut, 50% Developer
Addon Developer
Joined
Aug 12, 2010
Messages
192
Reaction score
0
Points
0
Location
Québec, QC
Actually, in your case, passing by reference would be statically safer.

Here it goes:
Code:
class Gauge1
{
public:
      Gauge1(VESSEL3* myVessel, const double& pressureKPA);
      ~Gauge1();

      void DoPressureCheck();

private:
      const double& m_pressureKPA;
};

Code:
Gauge1::Gauge1(VESSEL3* myVessel, const double& pressureKPA)
:m_pressureKPA(pressureKPA)
{
      // ...
}

void Gauge1::DoPressureCheck()
{
      double currentPressureKPA = m_pressureKPA; // here, you are accessing the real value, not a copy. This is the exact same thing as doing (*m_pressureKPA) if it was a pointer.

      // m_pressureKPA = 42; This won't compile, because you have a const reference.
      // If you wan't to play with the variable internally, remove the const
      // However, this violates encapsulation.
}
Note that you have to use the initialization list to initialize your reference.

And you would create your gauge like this:
Code:
VESSEL3* vessel = /* ... */ ;
double pressure = 42.0;

Gauge1 myGauge(pointerToVessel, pressure);
// or
Gauge1* myHeapGauge = new Gauge(pointerToVessel, pressure);

A reference cannot be null. Therefore, if you write something like :
Code:
Gauge1 myGauge(pointerToVessel, nullptr);
the compiler won't compile this and will point you to this line.

Also, a reference cannot be reassigned. In your case, this is an advantage, because that is exactly what you want.

C++ is statically-typed, use it at your advantage. The compiler is your friend. The more it detects error before you run the code, the more you are happy.
 

Col_Klonk

Member
Joined
Aug 29, 2015
Messages
470
Reaction score
0
Points
16
Location
This here small Dot
When using a low level debugger to trace this, you might find something like

Code:
Lea    eax, DoubleVariable      ; pointer to double variable
Push   eax                       ; reference pointer placed on parameter stack
..                                   ; other procedure parameters.. or goodies
Call    SomeFunction           ; the call to the procedure

It will come to this with those lousy bugs that don't go away

It's so much simpler using Asm :thumbup:
:cheers:
 

RisingFury

OBSP developer
Addon Developer
Joined
Aug 15, 2008
Messages
6,427
Reaction score
492
Points
173
Location
Among bits and Bytes...
I like using references, but only for functions that you call once at a time. If I have to store an outside variable, I make sure to use a pointer to it. A pointer always makes it clear that "this is not mine!"
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,615
Reaction score
2,335
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
I like using references, but only for functions that you call once at a time. If I have to store an outside variable, I make sure to use a pointer to it. A pointer always makes it clear that "this is not mine!"

Well for me, I translate it like that:

pointer* <==> 0...* objects
reference& <==> 1 object

If you need to pass something that has to exist exactly once (and could be modified), a reference is the best representation. Pointers allow 0 to multiple objects (array!). If you want that (e.g. optional parameters), a pointer is better
 
Last edited:

jedidia

shoemaker without legs
Addon Developer
Joined
Mar 19, 2008
Messages
10,875
Reaction score
2,129
Points
203
Location
between the planets
Additionaly, I have just learned that you can't have an STL-collection of references, because you can't have a pointer to a reference... while of course a pointer to a pointer is common practice.
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,615
Reaction score
2,335
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
Additionaly, I have just learned that you can't have an STL-collection of references, because you can't have a pointer to a reference... while of course a pointer to a pointer is common practice.

Well, you can, that depends on the implementation of the STL. But generally, the implementations assume pointers and optimize for them.
 

Col_Klonk

Member
Joined
Aug 29, 2015
Messages
470
Reaction score
0
Points
16
Location
This here small Dot
..while of course a pointer to a pointer is common practice.
Commonly used COM model (Object Orientated Programming - OOP).

.. because you can't have a pointer to a reference...
This is actually OOP.. (a pointer is a reference and visa versa..) you can go to any depths of pointers, but then again you must control it.. call it extended OOP ;)

C++, C-sharp..essentially MSofts dev kits are limited in their application of coding imagination.. so to speak!.. anyway a non-event.
 
Last edited:

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,615
Reaction score
2,335
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire

jedidia

shoemaker without legs
Addon Developer
Joined
Mar 19, 2008
Messages
10,875
Reaction score
2,129
Points
203
Location
between the planets
At it's basic cpu core level, a reference is a pointer, irrespective of language used

I think everyone's aware of that. Fact is, The VisualStudio compiler won't let you declare a pointer to a reference.

Well, you can, that depends on the implementation of the STL.

Wasn't even aware that there were other implementations of the STL than, well, the standard one.
 

Col_Klonk

Member
Joined
Aug 29, 2015
Messages
470
Reaction score
0
Points
16
Location
This here small Dot
I think everyone's aware of that. Fact is, The VisualStudio compiler won't let you declare a pointer to a reference.
Hence my comment on the limitation of Msofts dev kits...
I think it's really their compiler limitation where they don't want you to confuse them :rofl: which is a pity.. but we live with that!
 
Last edited:

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,615
Reaction score
2,335
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
At it's basic cpu core level, a reference is a pointer, irrespective of language used ;)
Visual Basic functions use parameters by reference -> a Pointer

No it is not. And don't cite assembler manuals before you have learned the differences.

Indirect addressing is NOT the same as a pointer or a reference.
A high level language is more than just the resulting object code (otherwise, we would be just writing macro assembler and could forget about all the nonsense)

Especially: A compiler can translate a reference into the same CPU instructions as a pointer. But it must not be the case - there are many situations in which a different translation is better, since the compiler already knows that a NULL reference is impossible.
 

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
As far as I can tell, not allowing a pointer to a reference isn't specific to Microsoft implementations.
 

Col_Klonk

Member
Joined
Aug 29, 2015
Messages
470
Reaction score
0
Points
16
Location
This here small Dot
High level languages are nothing more than macro languages, that have to be assembled, via optimising compilers, and hopefully that works out ok.
:)

---------- Post added at 11:57 PM ---------- Previous post was at 11:55 PM ----------

As far as I can tell, not allowing a pointer to a reference isn't specific to Microsoft implementations.
True.. it's general to most 'structured' languages, done in order to simplify compiler operations.
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,615
Reaction score
2,335
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
As far as I can tell, not allowing a pointer to a reference isn't specific to Microsoft implementations.

Yes, but it generally fails because STL template container classes try to create a pointer to a reference then, because they create a pointer to the template type.

If they would wrap the template type into a special element type, that is referenced with a pointer - but that means a more complex implementation, that is not as straight-forward anymore.

---------- Post added at 12:20 AM ---------- Previous post was at 12:18 AM ----------

You've lost it on that point.. I'm afraid ;)
Which renders that post Null and Void... try again :tiphat:


Sorry no. As smart as you try to be, you can sure answer the following question easily: Which data types does assembler know and how strongly are they typed?
 
Top