class Date{
int day;
int month;
int year;
public:
Date(int _day,int _month,int _year){
this->day=_day;
this->month=_month;
this->year=_year;
//functions
void PrintDate();
};
void Date::PrintDate(){
cout<<day<<"\\"<<month<<"\\"<<year<<endl;
return;
}
int main(){
const Date today(03,06,2017);
today.PrintDate();//error
return 0;
as you can see im getting error when im trying to print "today" instance, im not trying to change it so i dont understand what is the problem.
the error is "passing "const Date" as "this" arguments discards qualifiers"
Consider using a member initialisation list. It is better because it initialises the variables directly. When you use assignment like you have, the members get default values first, then they get re-initialised again with the assignment statements.
1 2 3 4 5
Date(int _day,int _month,int _year)
: // colon introduces member initialisation list
day(_day),
month(_month),
year(_year) {}
1 2
//functions
void PrintDate(); // One can't have a function declaration inside another function.
Please learn to indent your code, it will make things like missing braces more obvious.
One technique I used to ensure matching pairs of parentheses, brackets etc, was to to type the opening and closing bracket immediately, then go back and fill in what is supposed to be in between.
I am not a friend of member initialisation lists. Imagine real code with some logging and error checking. How would squeeze this in the list? It's probably possible, but makes the code less readable.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
#define LOG(...) // some logging function
class Date
{
int day;
int month;
int year;
public:
Date(int _day, int _month, int _year)
{
LOG("Entering %s\tday = %d, _month = %d, _year = %d", __FUNCTION__, _day, _month, _year);
assert(_day > 1 && _day <= 31);
this->day = _day;
assert(_month > 1 && _month <= 12);
this->month = _month;
assert(_year >= 0);
this->year = _year;
};
};
I think these lists are only needed to initialize consts.
I am not a friend of member initialisation lists. Imagine real code with some logging and error checking. How would squeeze this in the list? It's probably possible, but makes the code less readable.
Hi Thomas,
One doesn't have to squeeze it into the list, the object is not deemed to be created until the closing brace of the constructor, so one can do as much error checking (including calling other functions) as one likes. I guess one could so that if they weren't keen on or couldn't have exceptions. As I mentioned above, the member init list prevents initialising the members twice.
One can do a function try block, which throws if any of the arguments throw, or one could throw if invariants weren't met. One could do all the logging, error checking, and modifying of values in that function.