I know that C++ references are not objects, but seems that I can pass references as objects.
In the code below, v1 and v2 are references, and are assigned as double &v1 = x1 through the constructor. Then, while calling from foo(), should I have bar(double &) or bar(double)? Based on double &v1 = x1, shouldn't there be bar(double)?
This looks confusing to me. Can someone explain it?
#include <iostream>
class FooBar
{
private:
double &v1, &v2;
public:
FooBar(double &, double &);
void foo();
void bar(double &);
};
FooBar::FooBar (double &x, double &y): v1(x), v2(y) {}
void FooBar::foo()
{
bar(v1);
bar(v2);
}
void FooBar::bar(double &x)
{
std::cout << x << "\n";
}
int main()
{
double x1 = {0.5}, x2 = {1.5};
FooBar f(x1, x2);
f.foo();
return 0;
}
Then while calling from foo(), should I have bar(double &) or
bar(double)? Based on double &v1 = x1, shouldn't there be bar(double)?
In this case it doesn't matter, v1 is a reference and if you change it inside of bar, the variable that was used to initialized it will also change, regardless if the parameter of bar is declared as double or double&.
Have in mind that a reference is like a synonym to a variable. Even though the C++ standard does not specify how a compiler must implement references, every C++ compiler I know implements references as pointers. So basically, you are passing the memory address of the variable to the function anyway.
Related
Are there any methods in C++ I can use, such as overloading or templating, that would allow me to pass class instances as an argument to a cmath function? For example, if I had a class named “Point” (shown below), is there any way that I could perform the operation std::abs(Point(-4, -9)) and have it return Point(4, 9)?
#include <iostream>
#include <cmath>
class Point{
private:
double x, y;
public:
Point(double x, double y) {
this->x = x;
this->y = y;
}
// Approach 1 that I would like to avoid
static Point abs1(const Point &p1) {
return Point(std::abs(p1.x), std::abs(p1.y));
}
// Approach 2 that I would like to avoid
Point abs2(void) {
return Point(std::abs(x), std::abs(y));
}
};
int main()
{
Point pt1(-4.0, -9.0), pt2;
pt2 = std::abs(pt1) // <-- What I would like to be able to do
pt2 = Point::abs1(point_d); // <-- Function call 1 that I would like to avoid
pt2 = point_d.abs2(); // <-- Function call 2 that I would like to avoid
return 0;
}
Or am I restricted to using class based methods that would require me calling Point::abs(Point(-4, -9)) or Point(-4, -9).abs()? So in short, can I augment the cmath function in anyway to accept a class instance?
I have had a look around and I can’t find any information on the subject, however I am quite new to C++. So, I would appreciate any information on how this might be done, if it can be done, and whether such an action is ill-advised, and if so, why?
Thanks in advance.
You would do it like this.
#include <iostream>
#include <cmath>
class Point{
double x, y;
public:
Point(double x, double y)
: x(x), y(y)
{
}
friend Point abs(const Point &p1) {
return Point(std::abs(p1.x), std::abs(p1.y));
}
};
int main()
{
using std::abs;
Point pt1(-4.0, -9.0);
double x = 5.5;
// this will work even if Point is in its own namespace
// because of ADL
Point pt2 = abs(pt1);
// this works because for this function, we have pulled
// std::abs into the global namespace
double y = abs(x);
return 0;
}
Have a look at this reference page:
For calculating absolute values, in cmath you just have a bunch of overloads that operate on primitive types:
int abs(int j);
long int abs(long int j);
long long int abs(long long int j);
float abs(float j);
double abs(double j);
long double abs(long double j);
Since these functions are not templated, there is no way you can pass to them a Point class and get back another instance of Point. They can only receive a primitive type, and return the same type.
Something like this (similar in terms of syntax only) could only happen, if your Point class was convertible to one of these primitive types. E.g. in the following snippet, I defined class A, which is implicitly convertible to and from int, therefore when I call abs with an instance of A, it is automatically converted to int, passed to the appropriate overload of abs, and finally the result is converted back to A.
#include <cmath>
#include <iostream>
class A
{
public:
A(int x_) // implicit conversion from int
: x(x_)
{}
operator int()
{
return x; // implicit conversion to int
}
private:
int x;
};
int Foo(int x)
{
return x * 2;
}
int main()
{
A a1(-2);
A a2 = Foo(a1);
A a3 = std::abs(a1);
std::cout << "a2: " << a2 << "\n";
std::cout << "a3: " << a3 << "\n";
getchar();
}
But this is pretty much how far you can go with this trick, which I think doesn't cover what you want. I believe the best approach in your case is to create some utility function, that does what you want. I would rather go for a free function, instead of a static member, to not litter the class with unnecessary utility methods, i.e. something like this
namespace PointUtils
{
Point abs(const Point& p);
}
The two approaches you show are valid ways to do it. There is no way to use std::abs directly on your Point class.
Another way is to make your static abs1 function into a free abs function. If it's declaration is in a header file, it essentially overloads the std::abs function. In order to implement that as a free function, you would need to implement member functions to get x and y or make your free function a friend of you Point class.
Say I have a function that should not modify the parameters or anything else in the class, example:
bool isPossible(int x1, int y1, int x2, int y2) const {
return x1 < x2 && y1 < y2;
}
For clarity should I set all the parameters to const as well as the function itself or does it suffice with setting only the function as const (the way I have now)?
That is, should it instead be like this?
bool AABB::isPossible(const int& x1, const int& y1, const int& x2, const int& y2) const {
return *x1 < *x2 && *y1 < *y2;
}
There is no relation between function being const and parameters of function being const conceptually. They serve different purposes:
Const function indicates that function should not change class members
Parameters being const of function mean values of parameters should not change inside function
So if you want your function parameters to be const or not, you should decide separately from the function itself being const.
For example, in your particular case though indeed you could declare your function parameters as const since you aren't modifying them inside function (though probably it would not add much in this particular case).
Setting reference parameters as const makes more sense (when it is needed) as addressed in other answers.
Short answer: no.
The const in your example means that
some_object.isPossible(a,b,c,d);
treats some_object as const, but has no bearing to what the function does to a, b, c, or d.
If arguments are being passed by value (like x1, etc in your example), declaring them const is redundant and unnecessary since, when calling the function, the values provided by the caller are copied - changing them in the function has no effect on the caller.
If an argument is passed by reference or pointer, the const matters (with the meaning being that the argument passed is not logically changed by the function) if it is present. This is independent of the const on the function itself though. So it is possible for arguments to be const or non-const, independently of whether the function itself is. There is nothing wrong with
some_object.isPossible(a,b,c,d);
being permitted to change a and c (not specifying const) but not being permitted to change b and d (specifying them const). And these can be handled independently of whether some_object can change or not (i.e. if the member function itself is const).
The const modifier on a function has no bearing on it's parameters. It is only applicable to functions that belong to a class or struct, in which case it's usually referred to as a method. A const method simply means that the method will not modify the instance of the class it is called upon but makes no guarantees about it's parameters.
If you want to guarantee that the parameters are not modified, add const to the parameters. It's important to understand the difference between passing parameters by value and by reference. In this case, each parameter is given by value, so anyone calling this function already knows that the original variables given to this function cannot be modified by the function. The only benefit of using const is that you can't accidentally assign to your parameters. The situation is different for parameters passed by reference, where the presence of const is necessary if you want to guarantee that the original variables given to the function are no changed.
As previously mentioned const member functions and const function parameters are two different concepts.
The following code illustrates the differences:
#include <iostream>
class MyClass
{
public:
MyClass();
void PrintState() const;
void UpdateState(const int newA, const int newB);
private:
int a;
int b;
};
MyClass::MyClass()
: a(10), b(20)
{}
void MyClass::PrintState() const
{
/*
* Note: the following is not possible due to the member function being const.
* a = 30;
*/
std::cout << "A: " << a << ", B: " << b << std::endl;
}
void MyClass::UpdateState(const int newA, const int newB)
{
/*
* Note: the following is not possible due to the parameters being const.
* However, updating the data members is fine.
* newA = 30;
* newB = 40;
*/
a = newA;
b = newB;
}
For starters take into account that these two declarations declare the same one function
bool isPossible(int x1, int y1, int x2, int y2) const;
bool isPossible(const int x1, const int y1, const int x2, const int y2) const;
The both functions do not change the original arguments passed to the functions. Function parameters are its local variables.
Thus the using of the const qualifiers influences only on the body of the function.
The corresponding first definition of the function can be imagined the following way
bool isPossible(/* int x1, int y1, int x2, int y2 */ ) const
{
int x1, int y1, int x2, int y2;
//...
}
The second definition when the qualifiers are used can be imagined the following way
bool isPossible(/*const int x1, const int y1, const int x2, const int y2*/) const
{
const int x1, const int y1, const int x2, const int y2;
//...
}
For the caller of the functions it is entirely unimportant how the local variables are declared within the functions. It would be important if the corresponding arguments were accepted by the functions by reference. However for the functions above arguments are passed by values that is the functions deal with copies of arguments. Thus whether to use the qualifiers or not is not very important. It has only self-documented meaning for function body implementations.
Let's assume the the function calls some other function and passes the first own parameter by reference to the other function.
bool isPossible(/*const int x1, const int y1, const int x2, const int y2*/) const
{
const int x1, const int y1, const int x2, const int y2;
//...
call otherFunction( &x1 );
//...
}
In this case if you expect that the original value of x1 would be the same during all the function execution and that other called functions would not change the value of x1 by mistake it is better to declare the parameter with the qualifier const.
Consider the following example
#include <iostream>
void g(int *x) { *x += 10; }
void g( const int *x ) { }
struct A
{
void f(int x) const
{
int prev_x = x;
g( &x );
if (x != prev_x)
{
std::cout << "x = " << x << ". Oops, x was changed!" << std::endl;
}
else
{
std::cout << "x = " << x << ". x was not changed" << std::endl;
}
}
};
int main()
{
A().f(10);
}
The function output will be
x = 20. Oops, x was changed!
The problem is that by mistake the programmer forgot to cast the pointer to a const pointer like this
g(const_cast<const int *>( &x ));
To avoid such a mistake it makes sense to declare the parameter with the qualifier const
void f( const int x) const
{
//..
to select the correct overloaded function for the call
g( &x );
No, it's not required that you make the parameters be const as well. The way you are passing your arguments is by value so your parameters well be merely copies of the original.
The benefit of const parameters comes from passing pointers or values by reference in C / C++.
const function you mean const this pointer which means that that member function won't change or modify the class members not the parameters.
the parameters passed in by value shouldn't be modified so it's recommended to use them as const. this is useful where the body of the function is big and uses them so to avoid modifying them by accident pass them as constants. in your case it's ok to pass them as const or modifiable as long as there's no big code.
This question already has answers here:
How do you pass a member function pointer?
(6 answers)
Closed 9 years ago.
I have a class
class A{
A(/*constructor arguments*/);
double MethA(double);
};
And I want to pass the method MethA in a function that takes a pointer to a function :
double function(double (*f)(double), double x){
return f(x);
}
So what I'm doing is to call
A a(/*constructor arguments*/);
function(a.MethA,1.0);
but it doesn't compile.
I'm pretty sure that this question is answered somewhere else, but I couldn't find where because I'm not sure that the terminology I use is correct. Am I trying to pass a pointer on a class method as a function argument ? Or, to pass a function pointer as a member of a class... I'm confused :-(
When you need to use a pointer to member function, you need to pass two separate things:
what member function to call and
what instance to call it on.
In C++, you can't combine them in one construct, like you want to:
A a;
bar(a.foo);
is not valid C++.
Instead, you have to do this:
A a;
bar(a, &A::foo)
And declare and implement bar() accordingly:
void bar(A &a, void (A::*method)()) {
a.*method();
}
See Arkadiy's answer if you want to see how to properly use member function pointers.
BUT
As requested in the comments: if the compiler you are using supports lambdas (some without full C++11 do). You can do something like the following, which looks more like the syntax you are attempting to use.
Your definition for function changes to something like:
template <typename F>
double function(F f, double x){
return f(x);
};
a function template that accepts a parameter that is callable with a double.
At your call-site you do this:
A a(/*constructor arguments*/);
function([&](double x){return a.MethA(x);},1.0);
That generates a function object in-place that is bound to your class instance a by reference.
The template can be made fully typesafe with some magic in <type_traits>, but as-is it will give you template spew if you pass something very wrong.
It has to be a static function!
#include <iostream>
#include <cassert>
class A {
public:
static double MethA(double x) { return 5 * x; }
};
typedef double (*ftype)(double);
double function(ftype f) {
assert(f != NULL);
return f(7);
}
int main(int, char**) {
// expect "35\n" on stdout
std::cout << function(A::MethA) << "\n";
}
It has to be static because you can't access any of A's variables without knowing which A object are you refering to! If you need A's non-static member variables, you need to pass a reference to an a into the static function:
#include <iostream>
#include <cassert>
class A {
double fX;
public:
A(double x) : fX(x) { }
double methB(double x) const { return fX * x; }
static double MethB(double x, const A& a) {
return a.methB(x);
}
};
typedef double (*ftype2)(double, const A&);
double function_with_context(ftype2 f, const A& a) {
assert(f != NULL);
return f(7, a);
}
int main(int, char**) {
A a(6);
// expect "42\n" on stdout
std::cout << function_with_context(A::MethB, a) << "\n";
}
But it's sometimes better to use inheritance and polymorphism to achieve this sort of interface:
#include <iostream>
class MyInterface {
public:
virtual double f(double x) const = 0;
};
class A : public MyInterface {
double fX;
public:
A(double x) : fX(x) { }
double f(double x) const {
return fX * x;
}
};
double function(const MyInterface& o) {
return o.f(7);
}
int main(int, char**) {
A a(6);
// expect "42\n" on stdout
std::cout << function(a) << "\n";
}
I have two classes, ClassA and ClassB.
ClassA has three methods:
double Foo(double, ClassB);
double Bar(double (*f)(double));
double Baz(double, ClassB);
I would like to define a function Qux inside Foo, based on Baz but without the argument of type ClassB: i.e. of the kind "double Qux(double)" so that I can pass it to Bar:
double ClassA::Foo(double x, ClassB y)
{
// double Qux(double .) = Baz(., y)
Bar((*Qux))
}
Does some one have any idea?
I guess some will answer this is not the good way to do it. So just to explain the concrete situation, I am pricing financial assets using a numerical method (http://en.wikipedia.org/wiki/Simpson%27s_rule) in order to compute integrals:
ClassA: FinancialAsset
ClassB: PrincingModel
Foo: FinancialAsset.Price(date, PrincingModel)
Bar: FinancialAsset.SimpsonMethod(FunctionOneArgument)
Baz: FinancialAsset.FunctionTwoArguments(date, PrincingModel)
And I am looking for:
Qux: FunctionOneArgument(date) = FinancialAsset.FunctionTwoArguments(date, PrincingModel)
I am not sure what is the good way to address this structure. I you have a better / more c++'s way to do it, I'll take :)
Thanks
You can't do that exactly, because your Bar function is taking a pointer to a regular function, but you can use this instead:
class A {
...
public:
double Foo(double, ClassB);
double Bar(std::function<double(double)> f);
double Baz(double, ClassB);
};
double ClassA::Foo(double x, ClassB y)
{
auto Qux = [&](double x) { Baz(x,y); };
return Bar(Qux);
}
std::function is a more general way of representing function-like objects. You can convert a regular function, a lambda, or a function object to it.
Depending on whether you have C++11 or not, you either want std::bind and std::function or boost::bind and boost::function for older C++ versions.
binding allows you to take a function and bind 0 or more of the parameters, or rearrange the parameters. Indeed something you have above would look like this:
double ClassA::Foo(double x, ClassB y)
{
boost::function<double> baz = boost::bind(this, ClassA::Baz, _1, y);
Bar(baz);
}
And Bar's signature would take a boost::function instead of a function pointer.
Note my syntax might be slightly off for binding memeber functions, have a look at the documentation for details.
see here:
http://www.boost.org/doc/libs/1_53_0/libs/bind/bind.html
Or here: http://en.cppreference.com/w/cpp/utility/functional/bind
You can do it without changing any function signatures (and C++11 or boost), but I wouldn't suggest it if you can avoid it. It's ugly, not thread-safe, and in general not very nice:
#include <iostream>
struct B
{
// some data in B
int i;
};
struct A
{
//some data in A
double d;
// the functions you defined in A
double Foo(double x, B y);
double Bar(double (*f)(double));
double Baz(double x, B y);
};
// a poor substitutes for closures
struct
{
A *a;
B *b;
} hack;
double Qux(double x2)
{
// use the stored pointer to call Baz on x2
return hack.a->Baz(x2, *hack.b);
}
double A::Foo(double x, B y)
{
// store pointers for use in Qux
hack.a = this;
hack.b = &y;
// do something with x
d += x;
double result = Bar(&Qux);
return result;
}
double A::Bar(double (*f)(double))
{
// do something with d, call the passed function
d += 1;
return f(d);
}
double A::Baz(double x, B y)
{
// do something with the passed data
return x + y.i;
}
int main()
{
A a;
a.d = 1.25;
B b;
b.i = 2;
std::cout << a.Foo(.25, b) << std::endl; // should be 4.5
return 0;
}
This is a miniature version of a code I'm running in production. I have found that, my real code, behaves differently under gcc and Intel compilers and my best guess is an undefined behavior. Please consider the following sample code:
#include <iostream>
struct baseFunctor{
virtual double operator()(double x) const = 0;
};
class mathObj{
const baseFunctor *tmp1, *tmp2;
public:
void set(const baseFunctor& b1, const baseFunctor& b2){
tmp1 = &b1;
tmp2 = &b2;
}
double getValue(double x){
return (tmp1->operator()(x) + tmp2->operator()(x));
}
};
int main () {
mathObj obj;
struct squareFunctor: public baseFunctor {
double operator()(double x) const { return x*x; }
};
struct cubeFunctor: public baseFunctor {
double operator()(double x) const { return x*x*x; }
};
obj.set(squareFunctor(), cubeFunctor());
std::cout << obj.getValue(10) << std::endl;
return 0;
}
Could obj.set(squareFunctor(), cubeFunctor()); invoke undefined behavior?
Yes it most definitely does, because you are storing pointers to temporary values that are destroyed at the end of the statement, and then using them. Using a destructed object is undefined behaviour.
You need to create the values separately, and then call set with them:
cubeFunctor cf;
squareFunctor sf;
obj.set(sf, cf);
Note that you cannot solve this problem by storing the functors by value (unless you use templates), because that would cause slicing.
Also as a side note, you can change getValue to do
return (*tmp1)(x) + (*tmp2)(x);
To make it look a little prettier (and you still get dynamic dispatch).