How do I overload the pre and post increment operators for an object that is composed of a day and month to be printed as a std::string?
All of your overloadings have problems. One thing they all shouldn't do is returning an int
, and int day
is an integer.
DayOfYear operator++ () {return day++; }
Here, the return type is DayOfYear
, but it is supposed to be DayOfYear&
.
DayOfYear&operator++() {
++day;
return *this;
}
DayOfYear operator++ (int) {return ++day;}
Here, the return type is correct. You just have to return an object with the old value:
DayOfYear operator++(int) {
auto old_val = *this;
++*this;
return old_val;
}
Incorporated suggestions by @Deduplicator:
- note the use of auto. It simplifies the method and improves readability
++*this
may be preferred to calling the operator manually since it is shorter and easier to type
Same applies to --
operators
Implementing a print function is indeed simple but you have some choices:
This one prints the date to standard output. The downside is that the only place it prints its output is standard output:
void print () {
std::cout << getDay () << " / " << getMonth() << std::endl;
}
You may send an std::ostream
object and use it instead of std::cout
:
void print (std::ostream& os) {
os << getDay() << " / " << getMonth() << std::endl;
}
Converting an int
to an std::string
is very conveniently possible with std::to_string. It is defined in header <string>
, so make sure to include it:
std::string getDay () {
return std::to_string(day);
}
Edit:
As @Deduplicator pointed out, you may replace the print
function with overloading <<
:
friend std::ostream& operator<<(std::ostream& os, DayOfYear x) {
os << getDay () << " / " << getMonth() << std::endl;
return os;
}
overloading pre-increment and post-increment
what does "old" mean?
The method is a post increment. The current value ("old value") is returned and then the value is incremented ("new value").
++(*this) is assumed to use the pre-increment, and the original pre-increment definition does not have argument. However, it has *this here.
*this
is not an argument. The parentheses are not necessary, they are there for readability.
It's equivalent to ++*this
.
Pre and post increment operators in different classes
GCC rejects the code, because it first performs name lookup without considering the argument lists, and the name is found in two base classes. Clang accepts the code, but this is caused by a bug.
The solution is to add using
and create a separate class which inherits from A and B, and then inherit C from that class.
class A
{
public:
A& operator++(){return *this;}
};
class B
{
public:
B operator++(int){return *this;}
};
class AAndB:public A, public B
{
public:
using A::operator++;
using B::operator++;
};
class C:public AAndB
{
};
int main()
{
C c;
c++;
++c;
}
Overloading Pre-Increment Operator
You create a new iterator object, and (attempt to) return a reference to that.
The prefix-increment operator modifies this
object, and should return a reference to itself:
current = current->next; // TODO: Add checking for not going out of bounds or dereferencing a null pointer
return *this;
Related Topics
Is Multiplication and Division Using Shift Operators in C Actually Faster
Call a C Function from C++ Code
C++ Obtaining Milliseconds Time on Linux - Clock() Doesn't Seem to Work Properly
How to Propagate Exceptions Between Threads
/Usr/Lib/Libstdc++.So.6: Version 'Glibcxx_3.4.15' Not Found
How to Printf Uint64_T? Fails With: "Spurious Trailing '%' in Format"
C++ Catch Blocks - Catch Exception by Value or Reference
How to Convert Std::String to Lpcwstr in C++ (Unicode)
How to Create My Own Comparator For a Map
C++ Force Std::Cout Flush (Print to Screen)
The Benefits/Disadvantages of Unity Builds
Why Doesn't C++ Use Std::Nested_Exception to Allow Throwing from Destructor
Erasing from a Std::Vector While Doing a For Each