Understand C++ const functions - c++

I am new to c++ and im trying to write a simple c++ wrappers to integrate with this third party c++ library; which comes with bad documentation.
function to integrate with (this is all the documentation that came with this function):
virtual ImageCoord Raster::groundToImage(const XyzCoord & groundPt,
double desiredPrecision=0.001,
double* achievedPrecision=null) const
Text about function: This method converts the given groundPt (x,y,z in meters) to a returned image coordinate (line, sample in full image space pixels).
there is also some class documentation
Raster Class Ref
inherits from GeoModel
Public member functions:
virtual ImageCoord groundToImage (const XyzCoord &groundPt, double desiredPrecision=0.001, double *achievedPrecision=NULL) const =0
in my code i have:
//this is implemented correctly
const XyzCoord xyz(284971.17549099098, -126866.36533847413, 6350003.627515804)
double desiredPrecision = 0.000001;
double achievedPrecision = 0.0;
// not sure if this is what the documentation meant by "image coordinate" but it comes with the library
// ImageCoord(double line, double point)
ImageCoord imagePoints;
// the part im confused about, what is the proper way to invoke the above function, the below line was me trying out how to call the method
const Raster::groundToImage(&xyz, imagePoints);
Sorry for my ignorance in c++ but I've been baffled. I have lot of programing experience (8 plus years, just none with c++ so i understand programing terms, concepts and design patterns).
Im also trying to understand in the function defination what does this mean
const XyzCoord & groundPt
I was able to compile with
XyzCoord xyz(204971.17549099098, -106866.36533847413, 6350003.627515804);
Raster* service;
ImageCoord imagePoints = service->groundToImage(xyz); //segmentation error occurs on this line
but i then get a runtime error "Segmentation fault"

This is a non-static member function of a class named Raster.
You are supposed to invoke it via member access obj.groundToImage(/*args*/) where obj is an object of the class type to which the function belongs or a class type derived from that class.
Or, if the call happens inside another non-static member function of the same class or a derived class, it could just be groundToImage(/*args*/) which will call the function implicitly on the current object.
With virtual it may also be possible to invoke the function on an object of a base class of Raster, depending on where the virtual function has been declared first in the class hierarchy.
There are certain more specialized situations where a qualified call replacing groundToImage with Raster::groundToImage in either of the above could also be the intended behavior.
The const qualification of the function is irrelevant. It just means that the function can be called whether obj is const-qualified or not. Similarly the const-qualification on the function parameter is irrelevant. It just means that you can pass either a const- or non-const-qualified first argument. You don't have to make xyz const to be able to pass it. Only the other way around, passing a const-qualified expression to a non-const reference parameter is a problem. const is intended to signal that the function will not modify the argument and therefore doesn't care whether or not it is const-qualified.
const only makes sense when used in a declaration or type. Something like
const Raster::groundToImage(&ecef, imagePoints)
as a supposed function call doesn't make syntactical sense.
The function also expects up to three arguments of the specified types and returns a ImageCoord. You are not supposed to pass one as an argument. It is what the function returns.
The arguments should probably be xyz, desiredPrecision and &achievedPrecision given that you already declared them with the correct types.
It probably wants the last one as pointer because it is an out-parameter.
What the object on which the member function is called on is supposed to be is unclear from what you have shown. We don't know what ecef is though...

TL;DR:
ImageCoord imagePoint = someRasterObject.groundToImage(
xyz,
desiredPrecision,
&achivedPrecision
);
Or
ImageCoord imagePoint = somePointerToRasterObject->groundToImage(
xyz,
desiredPrecision,
&achivedPrecision
);
From the signature given:
virtual // A derived class's implementation of
// this function can be called via a
// pointer or reference to a parent
// class object
ImageCoord // This function returns an ImageCoord
// object
Raster:: // This is a member of the Raster class
groundToImage( // This function is named groundToImage
const XyzCoord & groundPt, // The first argument to this function is a
// reference to a constant XyzCoord
// object
double desiredPrecision=0.001, // The second argument is a double with a
// default value of 0.001 if not provided
double* achievedPrecision=null // The third argument is a pointer to a
// double with a default value of null if
// not provided
)
const // This function can be called on a
// constant Raster object
That means you need 2-4 things to call this function:
A (possibly const-qualified) Raster object to call the function on
An XyzCoord object to pass as the first parameter
(Optional) A double to pass as the second parameter
(Optional) A pointer to a double to pass as the third parameter
While nothing in your question explicitly states it, I would assume the function uses the 3rd parameter as an output. I would assume it writes the actually achieved precision to the double pointed to by the pointer you pass it, so you'll probably want to just pass it the address of a local double variable.

Each non-static method in a class is called on behalf of some object of that class (or some derived class), and the object is accessible within a method by an implicitly defined this pointer.
The const qualifier appended after the parameters' list of the method applies to that this value. In other words, it declares this of a type classname const* instead of classname*.
As a result the compiler will reject any attempts to modify the *this object from within the const-qualified method, so the method can be safely used on non-modifiable objects.
For example, the length() method of the std::string class is declared as
size_t length() const;
so when you use it like, say:
std:string s;
....
size_t len = s.length();
you can be sure the s variable will not be modified during calculation of len value.

Related

Using GSL Minimize in C++

I am having a problem with Minimization library in GSL. I am trying to implement the algorithm without derivatives, but in order to used i need to pass the function to minimize:
https://www.gnu.org/software/gsl/doc/html/multimin.html?highlight=minimization
I am following what they have there for the algorithm without derivatives, but when i try to used in my member class function: my_func i get this:
‘Class::my_func’ from type ‘double (Class::)(const gsl_vector*, void*)’ to type ‘double ()(const gsl_vector, void*)’
It seems the algorithm cannot use a member class function. My question is how to bypass this and transform the member class function into a normal (C like) function?
GSL uses params to pass arbitrary parameters into your function. Use a pointer to your object as "parameters".
Make a proxy function, a static member function in your class, which receives params. Inside this function, convert params to the proper type (pointer to your Class), and call the member function in it.
If your my_func is public, you can use a non-member ("global") proxy function.
class Class
{
double my_func(const gsl_vector*) // the real function
{
...
}
static double static_my_func(const gsl_vector* v, void* params) // proxy function
{
Class* object = static_cast<Class*>(params);
return object->my_func(v);
}
};
If your real function wants to receive additional parameters, you have to accommodate this somehow, e.g. making the parameters members of your Class, or (more complicated but more object-oriented) creating a temporary struct, which contains a pointer to your object and the additional parameters.

How to properly pass member function as argument in this situation in C++?

I want to pass a member function of my C++ class to another member function of the same class. I did some research and found these similar questions on SO.
Passing a member function as an argument in C++
Function pointer to member function
They don't cover my specific case in an identical manner, but I wrote my code and would think that I adjusted the right parts to make it work in my situation. However, the compiler seems to disagree with me on that...
I have the following setup in my C++ class:
CutDetector.h
class CutDetector {
double thresholdForFrameIndex(int frameIndex, vector<double> diffs, int steps, double (CutDetector::*thresholdFunction)(vector<double>diffs)); // should take other functions as args
double calcMean(vector<double> diffs); // should be passed as argument
double calcMeanMinMax(vector<double> diffs); // should be passed as argument
double calcMedian(vector<double> diffs); // should be passed as argument
}
CutDetector.h
double thresholdForFrameIndex(int frameIndex, vector<double> diffs, int steps, double (CutDetector::*thresholdFunction)(vector<double>diffs)) {
vector<double> window = ... init the window vector ;
double threshold = thresholdFunction(window);
return threshold;
}
However, passing the thresholdFunction as an argument like this doesn't work. The compiler complains with the following error:
error: called object type 'double (CutDetector::*)(vector<double>)'
is not a function or function pointer
Can anyone see why my setup doesn't work and suggest how I can make it so that it works? Basically what I want is to be able to pass any member function that calculates a threshold (i.e. calcMean, calcMeanMinMax, calcMedian) to the other member function thresholdForFrameIndex.
To invoke a pointer to member function, you need to supply an object:
double threshold = (this->*thresholdFunction)(window);
^^^^^^^^ ^
You can't call a member function without an instance of the class. You need to do something like this:
CutDetector cd;
double threshold = (cd.*thresholdFunction)(window);
Or if you have a CutDetector pointer somewhere:
double threshold = (pcd->*thresholdFunction)(window);
Or if thresholdForFrameIndex is a member function:
double threshold = (this->*thresholdFunction)(window);
I think it would be easier for you here to make calcMean, calcMeanMinMax and calcMedian static functions and treat like all others non-member functions. Others answers are correct, but in your case i guess that would be better for class design.

Function pointer to interface class function in child class constructor

I'm working on a project using interface based programming. The first part of this is for context just in case someone says I'm doing something completely wrong or has a different approach that fixes my issue.
I have a container class that includes several abstract interface classes. These define functions that return data I need.
This container class has a vector of parts that do not know about the container class, and therefore does not include the interface headers.
Every part is an object of the same type. When creating these objects, it passes a function pointer as an argument to the constructor of the child objects. This argument is a pointer to a function defined in one of the interface classes.
I'm trying to pass a pointer using &iTheInterfaceClass::theDataFunction to a constructor expecting U16(*pDataFunction)().
This results in the error
cannot convert 'U16 (iTheInterfaceClass::*)() {aka short unsigned int (iTheInterfaceClass::*)()}' to 'U16 (*)() {aka short unsigned int (*)()}' in initialization
If the parts include the .h file, I can get this to work, as I just match the prototype to include the namespace in the constructor. However, this breaks my abstraction. If each part includes a different interface, I have to create individual classes for each, even though the functionality is identical.
Is there anyway to get the prototypes to match without completely readjusting my strategy here?
As you've said yourself, your constructor expects the following type (excluding names):
U16 (*)()
However, you are trying to pass the following type:
U16 ( iTheInterfaceClass::* )()
Your constructor accepts free functions and class functions that are static, but you are trying to pass a non-static member function.They are not of the same type.
You could provide an overload for your constructor that takes in a member function as well as a reference or pointer to the object that the member function will be called on.
It could look something like:
public:
typedef U16( iTheInterfaceClass::*MemberFunctionPtr )();
MyContainer( iTheInterfaceClass& member, MemberFunctionPtr function ) : ... { ... }
Assuming you stored that information in some variables somewhere in the class, you could then call that function like so:
( member.*function )();
Where member is the variable that holds a reference to the object that you want to call the function on and function is the variable which holds the pointer to said member function.

Const changing variable values

I have a virtual get method that looks like this in the super class:
virtual double getPortagem() const;
double via_Ligacao::getPortagem() const
{
return 0;
}
And in their "child":
double getPortagem();
double auto_Estrada::getPortagem()
{
return portagem;
}
The thing that is bugging me is if I declare the child method as non const the results will be accoding to the values inserted but if I declare as a const method it will return me a memory position. Could you guys explain me this, please?
function overriding is not being done as you are making a new function in the child classes by declaring non const function which is not getting any match with the function in the superclass.
In C++11 you can use the keyword override to ensure that an intended override really is an override:
double auto_Estrada::getPortagem() override
{
return portagem;
}
Then you get a compilation error if it isn't an override, which this non-const function isn't (since it differs in const-ness from the base class method of the same name).
Instead of overriding the base class function this function shadows the base class function, so that if you call o.getPortagem() where o is const and of class auto_Estrada, the compiler won't find the base class const function, and complain.
In C++03 about the best you could do was to statically assert that the same named base class function could be called with the same arguments (it helped but wasn't guaranteed). Note that C++03 didn't have a static_assert. The usual way to do C++03 static asserts was via a typedef of an array, with negative size where you wanted a compile time error.
Regarding terminology,
what you call a "child class" is a derived class (C++ terminology) or subclass (more general computer science terminology, I believe originally from Smalltalk),
what you call "memory position" appears to be arbitrary bits in an uninitialized variable, interpreted as a floating point value, which is called an indeterminate value.
It's formally Undefined Behavior to use an indeterminate value, so anything can happen.

Silly C++ reference question

I do not know how to call a function with a reference in it :( It is a silly noob question I know.
The header is let's call it ref.h has a function in it that is:
virtual int funcName (Bike &biker, BikeArray &bikearray, int x, int y .... )
Within ref.h there is another header that is called Bike.h.
How do I call funcName from my main.cpp (obv. I included Bike.h and ref.h
I have called other functions from ref.h in my program, but the other functions did not have references to Bike in them, just variables... How do I declare everything?
What I have so far:
ref *ref;
Bike bike;
BikeArray bikearray;
int x, y;
ref = ref::createinstace(configFile);
ref->funcName(bike, bikearray, x,y);
ref->funcName should return results based on the configFile i passed. I have done this earlier with another function in ref.h, but that function only had int's and doubles... no objects to Bike ...
... and I get the Error "no matching function for call ref::funcName(Bike&, BikeArray&, int&, int&)
Sorry, I know this is a novice question!
You pass objects per reference as you would pass them per copy:
someObj.funcName(myBiker, myBikeArray, 42, ...);
Note that, if a function takes arguments per non-const reference, this indicates that the function might change them. (See here for more on that.)
Also, you cannot pass rvalues (temporary objects) as non-const arguments. That means that, if you have a function that returns a biker:
Biker getBikerByNumber(int num);
you can't use it as an argument to funcName:
someObj.funcName(getBikerByNumber(42), myBikeArray, 42, ...); // won't compile
because rvalues to not bind to non-const references. They do bind to const references, though (and also to the rvalue references to be introduced by the next C++ standard and already implemented by some compilers).
You call the function the same way regardless of whether its arguments are passed by value or by reference.
Bike foo;
BikeArray bar;
funcName(foo, bar);
Pass it values not pointers.
Bike biker;
funcName(biker, ...);
funcName is virtual so must be a class member function. You therefore need to have a reference or pointer to the class that it is a member of first.
It would have been enough for Bike to be forwardly declared but presumably Bike.h contains the class definition for Bike. BikeArray might be a class or a typedef, for example
typedef std::vector<Bike> BikeArray;
To call funcName you would then call it using . or -> on the class reference or pointer you have, then use an instance of Bike and an instance of BikeArray to be written into, plus whatever other parameters it requires.