When we start learing about "Function Overloading" then we are given with the example of functions of same name but with either different number of parameters or different datatypes of parameters like:
void add(int a, int b) //function 1
{
cout << "sum = " << (a + b);
}
void add(double a, double b) //funciton 2
{
cout << endl << "sum = " << (a + b);
}
int main()
{
add(10, 2);
add(5.3, 6.2);
return 0;
}
In this both the overloaded add functions are delared globally and they have same scope(global) also.
Now, my question is that if I define two functions with same name inside different blocks(one as global and other one inside a class) then will it still be called as "Function Overloading"?
Like:
void display() //function 1
{
cout<<"global diaplay() function";
}
class example
{
public:
void display(char a) //funciton 2
{
cout<<"display() function inside a class called by passing argument:"<<a;
}
};
int main()
{
display();
example M;
M.display('o');
return 0;
}
Explaination with an example will be very helpful.
Related
I need to implement the class Multiplier for a school exercise, but I do not understand how the teacher was able to call prod() without calling its inputs.
The goal of the code is to read a sequence of integers until the product of their absolute values is greater than 200.
Can somebody help me understanding please?
Here is the code:
#include <iostream>
using namespace std;
int main()
{
Product mult(200);
cout << "Enter numbers: " << endl;
do{
cin >> mult;
} while(!mult.exceed_limit());
cout << "The absolute values product is " << mult() << " . " << endl;
return 0;
}
A class can implement the "call" operation by overloading the operator() member function.
For example
class MyType {
public:
void operator()(int param) const {
std::cout << "MyType(int) called with: " << param << "\n";
}
void operator()() const {
std::cout << "MyType() called\n";
}
};
int main() {
MyType instance;
instance(12);
instance();
return 0;
}
Multiplier prod(100); - Multiplier must have defined a constructor that takes an integer as input, eg:
class Multiplier
{
...
public:
Multiplier(int value);
...
};
cin >> prod - Multiplier must have overloaded operator>> for input, eg:
class Multiplier
{
...
};
istream& operator>>(istream&, Multiplier&);
prod.limit_exceeded() - Multiplier must have defined a member limit_exceeded() method, eg:
class Multiplier
{
...
public:
bool limit_exceeded() const;
...
};
cout << prod() - Multiplier must have overloaded operator() (and the return value is then streamed to cout via operator<<), eg:
class Multiplier
{
...
public:
int operator()() const;
...
};
Lets see what we need
int main()
{
Multiplier prod(3);
A constructor. The parameter is probably the number of factors to be multiplied.
std::cout << "Enter numbers: " << std::endl;
do{
std::cin >> prod;
A way to "input" the factors.
} while(!prod.limit_exceeded());
A method to see if the entered factors equals the number of desired factors.
std::cout << "The product of the absolute values is " << prod() << " . " << std::endl;
A call operator that returns the resulting product.
return 0;
}
So lets do that:
struct Multiplier {
Multiplier(size_t n) : max_factors(n),num_factors(0),product(1) {}
size_t max_factors;
size_t num_factors;
double product;
double operator()() const { return product;}
bool limit_exceeded() const { return max_factors <= num_factors;}
};
Constructor takes number of factors, product holds the result, operator() returns the result and limit_exceeded() checks if all factors have been entered. Finally, a an overload for operator>> to read the factors:
std::istream& operator>>(std::istream& in, Multiplier& m){
double x;
if (in >> x) {
m.product *= x;
++m.num_factors;
}
return in;
}
It is a bit uncommon for std::cin >> prod; to not read prod but instead to modify prod, but thats fine.
Live Demo
I have two functions which call external library functions except one has two extra parameters (let’s say the extra parameters are always zero).
void func1(int a, int b)
{
libDoAThing(a, b);
}
void func1Special(int a, int b)
{
libDoAThingWithTwoExtraParams(a, b, 0, 0);
}
Is there any way to combine these methods into a single method which can be called as such:
func1<libDoAThing>{10, 10};
func1<libDoAThingWithTwoExtraParams>{10, 10};
I'm not sure how to handle the two extra parameters in the function call when templating.
If you can use at least C++11, you can fix the last two parameters with std::bind() or, I suggest, with a lambda function.
So you don't need a template parameter: you can pass the resulting lambda as an argument of func1() and call it inside.
The following is a full working example with lambda
#include <iostream>
void foo (int a, int b)
{ std::cout << "foo: " << a << ", " << b << std::endl; }
void bar (int a, int b, int c, int d)
{ std::cout << "bar: " << a << ", " << b << ", " << c << ", "
<< d << std::endl; }
void func1 (void(*f)(int, int), int x, int y)
{ f(x, y); }
int main ()
{
auto l { [](int a, int b){ bar(a, b, 0, 0); } };
func1(foo, 1, 2);
func1(l, 3, 4);
}
I am learning about functions and classes, and wrote my own code. I used the constructor to just initialize the variables. I have a function that is supposed to get the info I initialized with the constructor and allow me to display it. However, it doesn't want to work. I am not really sure what I am doing wrong. My error code says that I have unresolved externals because of my "void" function. I thought my function was not returning anything but rather just displaying the input it got from the initialization of the constructor.
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
class Berries {
string Nameofberries;
int Price;
public:
Berries (string N,int B)
{
Nameofberries = N;
Price = B;
}
void GetBerryInfo(const Berries& B)
{
cout << B.Nameofberries << endl;
cout << B.Price << endl;
}
};
void GetBerryInfo (const Berries& B);
int main ()
{
Berries Berryinfo1( "Raspberries", 7);
cout << GetBerryInfo;
system("pause");
return 0;
}
There are several mistakes.
void GetBerryInfo(const Berries& B)
{
cout << B.Nameofberries << endl;
cout << B.Price << endl;
}
should be
void GetBerryInfo()
{
cout << Nameofberries << endl;
cout << Price << endl;
}
==================================================================
void GetBerryInfo (const Berries& B);
should be removed.
==================================================================
cout << GetBerryInfo;
should be
Berryinfo1.GetBerryInfo();
==================================================================
All computer langauges are fussy, you have to get the details right, as well as understand the concepts.
This will do what you wanted:
# include <iostream>
# include <iomanip>
# include <string>
using namespace std;
class Berries {
string Nameofberries;
int Price;
public:
Berries (string N,int B)
{
Nameofberries = N;
Price = B;
}
void GetBerryInfo()
{
cout << Nameofberries << endl;
cout << Price << endl;
}
};
int main ()
{
Berries Berryinfo1( "Raspberries", 7);
Berryinfo1.GetBerryInfo();
system("pause");
return 0;
}
A couple of points on your mistakes:
GetBerryInfo() was declared inside the class. You don't need to re-declare it in the global scope. That 2nd declaration should be removed.
To be invoked, functions (like GetBerryInfo) must have () at the end of them like so: GetBerryInfo().
There is no point for GetBerryInfo() to take Berries as a paremeter. It is a member function that is part of the class Berries. It has access to all data members of a Berries instance already.
You don't need to use cout here: cout << GetBerryInfo; because the function body already sends the data members to cout. This function returns void so it doesn't make sense to send this to cout anyway.
I wish to create a constructor which takes input value from user, i.e value of a and b and then I wish to use these values in another function swap. This is more of general example. I wish to know where my concept is wrong.
#include <iostream>
using namespace std;
class swap_value
int a,b;
public:
swap_value()
{
cout<<"enter two numbers to swap";
cout<<"value of a is:";
cin>>a;
cout<<"value of b is:";
cin>>b;
}
void swap(int &a,int &b)
{
int temp=a;
a=b;
b=temp;
cout<<"value of a is :"<<a;
cout<<"value of b is :"<<b;
}
};
int main() {
swap_value obj;
obj.swap();
return 0;
}
#include <iostream>
using namespace std;
class swap_value {
int a,b;
public:
swap_value()
{
cout<<"enter two numbers to swap";
cout<<"value of a is:";
cin>>a;
cout<<"value of b is:";
cin>>b;
}
void swap(int &a,int &b)
{
int temp=a;
a=b;
b=temp;
cout<<"value of a is :"<<a;
cout<<"value of b is :"<<b;
}
};
int main() {
swap_value obj;
obj.swap();
return 0;
}
The thing that you should know is that all members of a class are accessible to all the methods of your class. So they don't need to be passed as parameters. The code you wrote doesn't compile (include error messages next time) because SwapValue doesn't have a method called swap() that takes no parameters.
Here is your code that does what you want it to. The change that I made was simply to make SwapValues::swap() take no parameters. Also, it is common practice to use UpperCamelCase for class names in C++. Indeed, it took me more time than it should have to notice that swap_values(){...} was your constructor for that reason.
#include <iostream>
using namespace std;
class SwapValues {
int a,b;
public:
SwapValues()
{
cout<<"enter two numbers to swap";
cout<<"value of a is:";
cin>>a;
cout<<"value of b is:";
cin>>b;
}
void swap()
{
int temp=a;
a=b;
b=temp;
cout<<"value of a is :"<<a << std::endl;
cout<<"value of b is :"<<b << std::endl;
}
};
int main() {
SwapValues sv;
sv.swap();
return 0;
}
Edit
To respond to the follow-up general question underlying the problem, the reason you are confused is because you are not sure about how the function gets access to a and b.
The short version is that methods of a class have built in access to all the attributes of the class.
The long version is that the instance of the class gets implicitly passed to methods of the class as an implicit parameter (called this in C++). So all functions of a class MyClass like
int MyClass::my_function( --parameters-- )
become
int MyClass::my_function(MyClass* this, --parameters--)
and the compiler, when it compiles code of such a function, sees
some_var = 1234;
will check firs if the function has a local variable or a local static variable or a parameter called some_var, and if there isn't, it will see if
this->some_var = 1234;
that is, it will check if `MyClass has an attribute called some_var.
In your case, in the working code we have
int temp = a;
so the compiler looks: is there a local variable called a, no local variable, is there a parameter called a, nope, next, what about this->a, the class does have an attribute called a so that's what we use.
So you always pass parameters, is the answer to your question but in the example of your function, that is done automatically. That's good because if you add an attribute to your class, you don't have to alter all the methods of your class to take an extra parameter, all the methods of the class will already have it.
In your first example, in fact, you should run this piece of code. It will show what I mean.
#include <iostream>
using namespace std;
class SwapValues {
public:
int a,b;
SwapValues()
{
a = 1;
b = 2;
}
void wrong_method(int &a, int &b)
{
std::cout << "wrong_method : "
<< "a = " << a
<< ", b = " << b
<< ", this->a = " << this->a
<< ", this->b = " << this->b << std::endl;
}
void right_method(int ¶m_1, int& param_2)
{
std::cout << "right_method : " << "a = " << a
<< ", b = " << b
<< ", param_1 = " << param_1
<< ", param_2 = " << param_2 << std::endl;
}
};
int main() {
SwapValues sv;
int c = 3;
int d = 4;
sv.wrong_method(c,d);
sv.right_method(c,d);
return 0;
}
Gives
wrong_method : a = 3, b = 4, this->a = 1, this->b = 2
right_method : a = 1, b = 2, param_1 = 3, param_2 = 4
This should demonstrate what I meant. The right and wrong because the wrong function has a name clash between the parameters and the attributes of the object. It makes errors possible and reflects bad design.
#include <iostream>
using namespace std;
class swap_value
{
private:
int a;
int b;
public:
swap_value()
{
cout<<"enter two numbers to swap";
cout<<"value of a is:";
cin>>a;
cout<<"value of b is:";
cin>>b;
}
void swap()
{
int temp=a;
a=b;
b=temp;
cout<<"value of a is :"<<a;
cout<<"value of b is :"<<b;
}
};
int main() {
swap_value obj;
obj.swap();
return 0;
}
The task is to create class, which counts the objects of its type, in every moment. Here is my code. The errors are:
1. the object has type qualifiers that are not compatible with the member function "counter::print";
2. return value type does not match the function type; - this was obwious really!
I corrected the errors and it gives me new one that I can't fix;
1. 'void counter::print(void)': cannot convert 'this' pointer from 'const counter' to 'counter &'
class counter {
private:
static int count;
public:
counter();
counter(const counter &from);
void print() const;
~counter();
};
counter::counter() {
++count;
}
counter::counter(const counter &from) {
++count;
cout << "Copy constructor:\t";
from.print(); // here is the error
}
void counter::print() const{
cout << "\t Number of objects = " << count << endl;
}
counter::~counter() {
--count;
cout << "Destructor:\t\t";
print();
}
int counter::count = 0;
counter f(counter x);
void main() {
counter c;
cout << "After constructing of c:";
c.print();
cout << "Calling f()" << endl;
f(c);
cout << "After calling f():";
c.print();
}
counter f(counter x) {
cout << "Argument inside f():\t";
x.print();
return x;
}
Firstly, change:
void print();
to:
void print() const;
because (a) it's a const method anyway and (b) you're trying to call it in a const context within your constructor.
For the second error here:
void f(counter x) {
cout << "Argument inside f():\t";
x.print();
return x; // 2 - nd error
}
it should be fairly obvious that you can't return a value from a void function. Either change it to:
counter f(counter x) {
cout << "Argument inside f():\t";
x.print();
return x;
}
or simply don't return anything:
void f(counter x) {
cout << "Argument inside f():\t";
x.print();
}
void print();
You have declared a non-const member function, which means it cannot be called by const instances.
from.print(); // 1 - st error
Here the type of from is const counter& which means it cannot call the print function. Instead make your print function const.
void print() const;
void counter::print() const { ... }
return x; // 2 - nd error
Why are you returning anything from a function with a void return type?