Function that does same things for different parameters - c++

I have two functions that do the same thing: they add two numbers. One adds two numbers which are members of the class, the other adds numbers given by the user, outside the class.
Is there any way to write one single function that adds two numbers and checks whether the arguments are user input or class members?
void myclass::add(){
cout<<this->a+this->b;
}
void myclass::add(int a,int b){
cout<<a+b;
}

While you cannot really do it in a single function the common approach would be to write the more flexible of the two and use the other one just as a dispatcher:
void myclass::add(int a, int b) {
std::cout << (a+b);
}
void myclass::add() {
add(a,b);
}
Now, there are a different number of smells in this code... a function name reused to act on members or only inputs is one (a function that does not touch the object's state already smells at it not being a member, or being a static one). Printing inside a function called add (should it not return the values?)...

Disclaimer : I don't encourage such coding.
Ok, here's a method
void myClass::Add(int& a, int& b)
{
if (&a==&this->a)
{
std::cout << this->a + this->b
} else {
std::cout << a+b;
}
}
Ofc , things like myClass->Add(10,4) won't work... you will need some stack variables to hold the 10 and 4 variables.

So you want a single function that can have two different parameters? It isn't possible.
void myclass::add(int a, int b)
{
cout << a + b << endl;
}
Is what you want; but you can overload the function:
void myclass::add()
{
cout << memberA + memberB << endl;
}
In my opinion, this is a much better solution than having a single function that checks whether the variables are members or not; it makes your code readable. Don't be afraid to overload functions - it's one of those things that makes C++ awesome. I've created a class to demonstrate this:
class myClass
{
public:
myClass() : memberA(0), memberB(0) {}
~myClass() {}
void setNumbers(int a, int b)
{
memberA = a;
memberB = b;
}
void add(int a, int b)
{
cout << a + b << endl;
}
void add()
{
cout << memberA + memberB << endl;
}
private:
int memberA;
int memberB;
};
int main()
{
myClass m;
m.setNumbers(1, 2);
m.add();
return 0;
}
I've tested the add function with and without parameters and they both output the same result. The former because I used a setNumbers(..) function. Effectively, your first scenario of having two functions is the most apt solution to begin with.

In you realy wanted a single function, the way to do it is with optional default parameters.
Your declaration will be
void add(optional<int> a = optional<int>(), optional<int> b = optional<int>() );
Then in your implementation:
a ? a.get() : this->a
A benefit of this approach is that you can mix members and parameters. For example:
obj.add(1);
obj.add(optional<int>(), 2);

Related

C++ (C++98) functor with multiple constructors?

Is it possible to create a functor with multiple constructors? I want to be able to use the functor in various ways, initializing its various members in different ways, all depending upon which constructor is used to set it up initially.
But is there a more elegant solution than the one I propose here using functors with multiple constructors?
This added level of reuse would play very well in the communications wire protocol interpreter I am writing. A particular wire (or a subset of wires) in a communications line can often serve different purposes, depending upon the specific protocol in use. I'd thus like to be able to create a small set of functors that can be adaptable, within reasonable parameters, rather than having to create a large set of very specific functors, each of which has comparatively little adaptability.
The smaller set of highly-adaptable functors would then be used, one at a time, as a parameter to a template function in another class, which function can either read or write data according to the "rules" embodied within the functor parameter used to call that template function.
My aim is to make the code as generic as possible, to allow many different permutations of protocols and sub-protocols to be used with the same basic code.
I'm not sure I understand your question. A straight answer is: yes you can, you can even overload the operator().
class MyFunctor {
public:
MyFunctor(int a) : a(a), b(0.0) {}
MyFunctor(double b) : a(0), b(b) {}
int operator()(int c) const { return a + c; }
double operator()(double c) const { return b + c; }
private:
int a;
double b;
};
MyFunctor fromInt(2);
MyFunctor fromDouble(2.1);
std::cout << fromInt(3) << std::endl; // Print 5
std::cout << fromInt(3.1) << std::endl; // Print 3.1
std::cout << fromDouble(2) << std::endl; // Print 2
std::cout << fromDouble(2.2) << std::endl; // Print 4.3
However, I feel this violate the Single responsibility principle. A better solution might be to create several small functors and choose the best one using a factory.
class MyFunctorInt {
public:
MyFunctorInt(int a) : a(a) {}
int operator()(int c) const { return a + c; }
private:
int a;
};
class MyFunctorDouble {
public:
MyFunctorDouble(double b) : b(b) {}
double operator()(double c) const { return b + c; }
private:
double b;
};
MyFunctorInt createFunctor(int a)
{ return MyFunctorInt(a); }
MyFunctorDouble createFunctor(double b)
{ return MyFunctorDouble(b); }
template<class Callable, class Real>
void myGenericFunction(const Callable &f, Real a)
{ std::cout << f(a) << std::endl; }
myGenericFunction(createFunctor(2),3); // Print 5
myGenericFunction(createFunctor(2.2),3); // Print 5.2
This probably scales better, since if you want to add a new capability to your code, e.g. for strings, you can just create a new file in which there is a new class MyFunctorString and a new overload to createFunctor(std::string). You can easily unit-test this new class, and you do not have to worry about interactions between various overloads. For instance, the first time I wrote the code for MyFunctor, I forgot to initialise all the members to 0, which lead to undefined results.

Do not use class member function inside class

I want to write an object-oriented wrapper around old C-style functions, while keeping the actual function names the same. Take a look at an example:
#include <iostream>
void doStuff(int a, float b)
{
std::cout << "a = " << a << ", b = " << b << "\n";
}
class Stuff
{
private:
int a;
float b;
public:
Stuff(int newA, float newB) : a(newA), b(newB) { }
int getA() { return a; }
float getB() { return b; }
};
class Widget
{
public:
void doStuff(Stuff s)
{
doStuff(s.getA(), s.getB()); //error: no matching function for call to 'Widget::doStuff(int, float)'
}
};
int main()
{
Widget w;
w.doStuff(Stuff(42, 3.14f));
return 0;
}
In this example, void doStuff(int a, float b) is the old C-function. Because in my real code, its equivalent is in an external library/header file, I cannot change its name. Next, Stuff is a container for keeping the values void doStuff(int a, float b) needs. The important things happen in Widget: void Widget::doStuff(Stuff s) should be the actual wrapper. I now expect doStuff(s.getA(), s.getB()) to call the old C-style function void doStuff(int a, int b) but the compilation fails with the given error.
Is it possible to make this code work without changing the name of the both doStuff functions? One option I already thought of is surrounding void doStuff(int a, float b) by some namespace. This works, but seems like very bad practice to me.
My compiler is mingw-w64 with g++ 5.2.0, so C++11 and C++14 are available.
The doStuff(Stuff s) method in your class hides the global function doStuff(int a, float b). If you want to call the global doStuff function, you have to use the scope resolution operator :: (::doStuff(s.getA(), s.getB());)
Try making your call like this:
::doStuff(s.getA(), s.getB());

C++ inheritance, calling the given classes function instead of its parent?

Really bad title, couldn't think of how to word it, sorry.
So say I had the following code:
class A {
virtual int getSize() {
return 0;
}
}
class B : public A {
int getSize() {
return 32;
}
}
void doStuff(A a) {
std::cout << a.getSize() << std::endl;
}
int main() {
B b;
doStuff(b);
}
It would print out 0, however I want it to print out 32. In other words, I want to pass it the class and it prints out that classes function, so I could create a class C, where the size is 64, and if I pass that C instance to the doStuff function, I want it to print 64.
Is there any way I can do this in C++, would I have to use templates or some fancy C++ feature I don't know about?
A one-byte patch:
void doStuff(A &a) {
std::cout << a.getSize() << std::endl;
}
Your version takes the argument by value, which means that the function makes a copy of b (a copy which is an A) and then calls the copy's getSize(). In this version, the function takes the argument by reference, and calls b's own getSize(), which is B::getSize().
You should use pointers, or even better: smart pointers! That way, the function of the runtime type gets called. It's a basic example of polymorhpism. If you want to avoid pointers, Beta's slicing approach is equally valid.
#include <iostream>
#include <memory>
class A {
virtual int getSize() {
return 0;
}
}
class B : public A {
virtual int getSize() {
return 32;
}
}
void doStuff(std::shared_ptr<A> a) {
std::cout << a->getSize() << std::endl;
}
int main() {
std::shared_ptr<A> b(new B());
doStuff(b); // Will output '32'.
}
This should correctly call the function as implemented by B.
Slicing the object is one approach, and in addition I think you're asking for, I think, a pretty straightforward use of polymorphism in C++. http://www.cplusplus.com/doc/tutorial/polymorphism/
That's almost immediately applicable, just call your class A Shape, and B and C could be Square and Triangle. Your DoStuff function could take a pointer to a Shape, then you can pass it a triangle or a square, and when you deference the Shape in the function, it will call the correct function.
So you'd have (also you need to make the members public, I think):
class A {
public:
virtual int getSize() {
return 0;
}
};
class B : public A {
public:
int getSize() {
return 32;
}
};
void doStuff(A* a) {
std::cout << a->getSize() << std::endl;
}
int main() {
B b;
doStuff(&b);
}

Default argument in c++

I am new in c++ i have a question on default argument.
If there a function with a following prototype
void f(int=10,int=20,int=30,int=40)
If this funcion is called by passing 2 arguments to it,how can we make sure that these argumnts are treated as first and third whereas, the second and forth are taken as defaults.
You can't. Arguments to functions match the parameters in order. You can use overloading instead of default arguments like this:
void myFunc(int a,int b,int c,int d);
void myFunc(int a,int c) {
myFunc(a,20,c,40);
}
That's not how default arguments in C++ work. If you pass two arguments to function f, they will always stand in as the first two arguments, while the last two would be 30 and 40.
In other words, C++ functions only support positional parameters.
Shouldn't be possible. They'd be treated as the first two.
You can just create a function with a different name, taking two arguments and calling f.
Alternatively, if you want to emulate named arguments, you can use something similar to fluent interfaces. Example:
#include <iostream>
using namespace std;
int f_impl(int a,int b, int c, int d){
cout << a << " " << b << " " << c << " " << d << endl;
return 42;
}
struct f{
int _a, _b, _c, _d;
f() : _a(10), _b(20), _c(30), _d(40){}
f& a(int a){ _a = a; return *this;}
f& b(int b){ _b = b; return *this;}
f& c(int c){ _c = c; return *this;}
f& d(int d){ _d = d; return *this;}
int operator()(){ return f_impl(_a, _b, _c, _d); }
};
#define F(x) (f()x())
int main(){
f().a(100).c(300)();
cout << F(.b(1000).d(4000)) << endl;
return 0;
}
Output:
100 20 300 40
10 1000 30 4000
42
As other people said you can't do that in C++.
But you can create struct/class with four integer members that initialized to values you defined. And you will pass it as a parameter to the function.
Example
struct Param
{
int a;
int b;
int c;
int d;
Param() : a(10), b(20), c(30), d(40) {}
void setA(int value) { a = value; }
void setB(int value) { a = value; }
void setC(int value) { a = value; }
void setD(int value) { a = value; }
}
void f(Param& param) {}
Param param;
param.setA(67);
param.setC(9);
f(param);
The feature you are asking for is called 'Named Parameters'.
Default parameters and Named parameters combined give you lot more options to do things like you suggested but unforunately, C++ doesn't have named parameters. However, some other languages like C# and VB and probably Python have named parameters
Default arguments will be assigned from last if necessary.
http://en.wikipedia.org/wiki/Default_argument
Actually you can have named parameters in C++ with a little help from boost::parameter ( also mentioned in the wiki article on named parameters ).

Dependent variables in C++?

I tried asking before but I wasn't very clear so I'm re-asking it.
I want to have a variable that depends on the value of another variable, like b in this example:
int main(){
int a;
dependent int b=a+1; //I'm just making this up
a=3;
cout << b; //prints 4
a=4;
cout << b; //prints 5
}
Of course, this does not exist in C++, but this is what I want.
So instead I tried making a function:
int main(){
int a;
int b(){ return a+1; } //error
a=3;
cout << b(); //would print 4 if C++ allowed nested functions
a=4;
cout << b(); //would print 5 if C++ allowed nested functions
}
The above doesn't work because C++ doesn't allow nested functions.
I can only make functions outside of main(), like this:
int b(){
return a+1; //doesn't work because a is not in scope
}
int main(){
int a;
a=3;
cout << b();
a=4;
cout << b();
}
But this does not work because a is not in the same scope as b(), so I would have to pass a as a parameter and I don't want to do that.
Are there any tricks to get something similar to a dependent variable working in C++?
What you need is a closure. If you can use C++ 0x features, you are in luck. Otherwise, you can define one manually:
#include <iostream>
using namespace std;
struct B
{
const int & a;
B(const int & a) : a(a) {}
// variable syntax (Sean Farell's idea)
operator int () const { return a + 1; }
// function syntax
int operator () () const { return a + 1; }
};
int main()
{
int a;
B b(a);
a = 3;
cout << b << '\n'; // variable syntax
a = 4;
cout << b() << '\n'; // function syntax
}
You can also define B inside main, but some compilers would not like it.
The C++ 0x lambda syntax looks like this:
auto b = [&]() { return a + 1; }
The [&] means that the lambda captures local variables by reference.
If you're using C++0x (GCC 4.5+, Visual C++ 2010), you can use lambdas:
int a = 5;
auto b = [&a]{ return a + 1; };
std::cout << b() << std::endl;
Depending on what you're doing, though, there are probably cleaner solutions - possibly some variation of the classic "method that takes in 'a' and returns 'b'"
You could define a class that had a member a, and then a function b() that returned the value of a+1. A basic implementation would be something like:
class Dependent {
public:
Dependent(void) { m_value = 0; }
void set(int value) { m_value = value; }
int b(void) { return(m_value + 1); }
private:
int m_value;
};
int main(){
Dependent a;
a.set(3);
cout << a.b();
a.set(4);
cout << a.b();
}
You could add operator overloading as appropriate to make it work more like normal integers if you so desired.
This is possible if you use lambda functions (c++0x), because they can capture local variables.
Example:
int main()
{
int a;
auto f = [&] () -> int { return a + 1; };
a = 3;
std::cout << f() << std::endl;
a = 4;
std::cout << f() << std::endl;
return 0;
}
Result:
4
5
(See http://ideone.com/MlzX7 for proof)
A simple approach is to use pre-processor macros, nothing C++ specific about it though:
#define b ((a)+1)
int main(){
int a;
a=3;
cout << b;
a=4;
cout << b;
}
#undef b
Are you OK using C++0x ? if yes,
int main()
{
int a = 10;
auto b = [&a]() -> int { return a + 1; };
cout << b() << endl;
}
Since, it is not tagged with c++0x, you can use nested classes instead of nested functions. This column from Herb sutter would help you for existing c++. http://www.gotw.ca/gotw/058.htm
The above doesn't work because C++ doesn't allow nested functions.
You can simulate that using nested structure. In C++0x you can make use of lambda function, which provides the same means of function inside function.
Define a class called LinkedInt or something that behaves like an int, but has a RelatedTo relationship on itself and an additional member that is a function pointer to the function to evaluate when computing the integer's value. Pretty straightforward. Let me know if you need some pointers on the coding.
The short answer is that OOP is more than enough to bury this problem.
I want to have a variable that depends on the value of another
variable, like b in this example:
I see you just need a reference variable:
int a;
int &b =a;
a=10;
cout << b; // 10
Why C++0x lambdas do come for this, I dont understand.