All operators can be overloaded with the exception of the sizeof, typeid, member-of (.), pointer to member (.*), ternary conditional (?:) and scope resolution (::) operators.
Operators may be unary (those that accept one operand) or binary (those that accept two operands). The ternary conditional operator is the only operator that accepts three operands but it cannot be overloaded.
Before overloading an operator, you must first consider the types of its operand(s) and also the type of its return value. All operators must return something, whether it is the logical NOT of an object (a unary operation) or the sum of two objects (a binary operation). However it's easy to get carried away with overloads in order to cater for every possible combination of types, and this can quickly lead to code duplication, inconsistencies and code that is much harder to maintain.
Ideally, all operators should be implemented as free functions (global functions). In so doing you gain the advantage of implicit conversion between types, thus reducing the number of overloads required for any given operation. The only operator overloads that must be implemented as member functions are the copy and move assignment operators, so let's begin with those.
Let's consider a class that encapsulates a year. We'll assume negative years denote BC and positive years denote AD, thus we'll use a signed integral as our representation. However, there was no year zero (we went from 1BC to 1AD), thus our class has an invariant -- it must not be zero.
class year
{
private:
int64_t m_data; // 64-bit signed integral
public:
year (int64_t y): m_data {y} { if (!y) throw std::range_error ("Error: no year zero!"); }
year (const year& y): m_data {y.m_data} {}
year (year&& y): m_data {std::move (y.m_data)} {}
year& operator= (const year& y) {m_data = y.m_data; }
year& operator= (year&& y) { m_data = std::move (y.m_data); }
~year () {}
};
Our class has one conversion constructor which allows us to implicitly convert from any 64-bit integer to a year. However, since the language has built-in conversions for all integrals we can implicitly construct a year from any integral, including a char, an int, a long, a short and so on. The only integral type we cannot implicitly convert is an unsigned 64-bit integral since this could exceed the bounds of our signed integral by up to an order of two. However, the compiler should warn us about this "narrowing" and helps us keep the class as simple as possible.
Note that the conversion constructor is the only constructor that maintains the invariant (non-zero years). Since the copy and move constructors can only work with pre-existing instances of our year class, those instances would not exist unless they had originally been constructed through conversion.
The copy and move assignment operators also cater for pre-existing instances of our year class, but we can also assign from any signed integral because we provided a conversion constructor to cater for this. This makes it possible to perform the following:
year y {2014};
y = -1;
The first statement initialises a year with the literal integral 2014. That is, the value 2014 is implicitly converted to an int64_t (which is what the conversion constructor expects), and the constructor instantiates a year object with that value. The second statement replaces that value with the literal integral -1 even though we did not provide an assignment operator overload to cater for this. Behind the Scenes, the compiler constructs a temporary year object from the literal (just as it did with 2014), and then uses that temporary object to perform the actual assignment. The temporary object falls from scope at the end of the statement.
The stream insertion and extraction operators often cause problems for new programmers in the mistaken belief that all operators related to a class should be members of that class just as the copy and move assignment operators must be. However, this is not the case; all other operator overloads should ideally be non-member functions whenever possible, especially when the return value is of a different type. In this case the return value is a reference to the stream being operated upon. We cannot provide these overloads as members of the stream nor as members of the type, therefore we have no option but to define them as free functions:
std::ostream& operator<< (std::ostream& os, const year& y)
{
return os << y.m_data;
}
The problem with this is that year::m_data is private. We could provide a public accessor (in many cases this would be the preferred option), but we must also never expose an interface without good reason. If this were the only function that actually required that accessor then it would not make sense to provide one. A public accessor is intended to be used by anyone and everyone. In this case we could simply return the member by value (and thus maintain encapsulation of the invariant), but in a more complex object we may not wish to expose the entire representation in this way because returning by value can be expensive in terms of both performance and memory. Returning by constant reference is another option but, again, this could expose far more than we wish to expose, which ultimately undermines the encapsulation. The best solution is simply to declare those functions that require private access as friends of the class:
class year
{
// ...
friend std::ostream& operator<< (std::ostream&, const year&);
};
Note that a friend is not a member of the class that declares it a friend, nor does it undermine encapsulation (if anything, it enforces it). The best way to think of it is to examine the three logically distinct things that every ordinary member function declaration specifies:
1. The function has private access to the class representation.
2. The function is in the scope of the class.
3. The function must be invoked upon an instance of the class (has a 'this' pointer).
A static member function declares the first two while a friend only declares the first. It therefore follows that if you believe a friend undermines encapsulation, then you must also believe every member function also undermines encapsulation -- and to a much greater degree. But you are the author of your own class' encapsulation rules; it's entirely up to you how you implement them, whether those implementations are within your own class member functions, your own static member functions or your own friends of the class.
Although friends are not physically members of your class, it would not be entirely wrong to think of them just as if they were. A friend declaration is itself a declaration so there's absolutely nothing to prevent you from defining it inline:
class year
{
// ...
friend std::ostream& operator<< (std::ostream& os, const year& y)
{
return os << y.m_data;
}
};
However, to keep your interface declaration "clean", it is best to place the implementation details outside the declaration, preferably alongside the other class member implementations.
Compound operators such as the increment-assign operator (+=) are often implemented as member functions, however there's no practical reason to do so, especially if you want to take advantage of implicit conversion. Use free functions wherever possible:
year& operator+= (year& lhs, const year& rhs)
{
lhs.m_data += rhs.m_data;
if (!lhs.m_data) throw std::range_error ("Error: no year zero!");
return lhs;
}
The above function must be declared a friend since it requires private access to the representation. However, note that you now have two places where you must check the invariant. Rather than duplicating the code, it would make sense to place that code in a private member function:
class year
{
// ...
private:
void check_invariants { if (!m_data) throw std::range_error ("Error: no year zero!"); }
};
Now the conversion constructor and increment assign operator can be simplified by calling this common method:
year::year (int64_t y): m_data {y} { check_invariants(); }
year& operator+= (year& lhs, const year& rhs)
{
lhs.m_data += rhs.m_data;
check_invariants();
return lhs;
}
With that done, all other increment operators can now be expressed in terms of this one overload without requiring friendship themselves:
// addition
year& operator+ (const year& lhs, const year& rhs)
{
return year {lhs} += rhs;
}
// prefix increment
year& operator++ (year& lhs)
{
return lhs += 1;
}
// postfix increment
year operator++ (year& lhs, const int)
{
year temp {lhs};
lhs += 1;
return temp;
}
All other operators can be implemented by the same means.
Remember, with the exception of the copy and move assignment operators, all other operator overloads should be implemented as free functions, with friend access only where required. Operators that are variations of each other (such as the increment operators), should be implemented in terms of one of those operators.
In some cases it can be helpful to provide a named member function in addition to or in place of an operator overload. For instance, the std::string& std::string::append (const std::string&) member function is synonymous with the std::string& operator+= (std:string&, const std::string&) operator overload. The first is implemented as a named member function, the second as a free function, where the free function simply invokes the member function. In cases where an operation might not be regarded as intuitive, a named member function is usually the best choice because the name can better express the notion of the operator than an operator alone can.
A template function is used when you want to write some kind of function that can be applied to different data types. It is a form of overloading, but you don't have to actually write all of the overloaded variants.
write a program that reads a phrase and prints the number of lowercase latters in it using a function for counting? in C program
This is not a question.
see pages 43-49 in Principles of Program design by M. A. Jackson, 1975
Q.1 Write a program to print first ten odd natural numbers. Q.2 Write a program to input a number. Print their table. Q.3 Write a function to print a factorial value.
A template function is used when you want to write some kind of function that can be applied to different data types. It is a form of overloading, but you don't have to actually write all of the overloaded variants.
Into the source program.
Reusability in Java means that once you write some code, you can use it over and over again - if you write it so that it can be reused. For example, if you write a Enumeration-Iterator adapter, or some code that lets you treat an Enumeration - Java legacy code - as an Iterator - shiny NEW Java code - then you can use it not only in your animal simulation program, but also in your Jacuzzi interface program.
write a program that reads a phrase and prints the number of lowercase latters in it using a function for counting? in C program
You can write a program without specifying its prototype when the function returns an integer.If the prototype is not mentioned the compiler thinks that the return type of the function used is integer.When making program which return integer you can ignore writing the protoype.
#include<
May be link might help -> http://www.allinterview.com/viewpost/408298.html There it is implemented through...... Operator Overloading!
void mynullfunction () {;}
Write a function that implements an algorithm that checks to see if a particular integer is prime (returning a boolean). Write a program that uses that function on each number from 1 to 100, and if true, displays that number.
In Windows, use notepad.exe; in linux, use program xedit.
It is not possible. In C, any program must have at least one function to be able to compile and execute properly: the function main()
This is not a question.