0

I'm writing a program in which I inherit from another class in C++ and override a couple of methods. Because I only wanted to add one line to these methods, I tried to call the method in the base class and add a line below it. I got the following error.

"Unhandled exception at 0x00FA4456 in Ch.12.exe: 0xC0000005: Access violation reading location 0x67525A64."  

This was the closest (as I understand it) that I could get to "super" in java.

Simplified version of the class

using namespace std;

#include <iostream>
#include <string>
#include "dateType2.h"

class extDateType : public dateType
{
private:
    string monthString;
    void updateMonthString()
    {
        string months[12] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
        monthString = months[getMonth()];
    }
public:
void printDateString()
{
    string months[12] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
    cout << months[getMonth()];
    cout << " ";
    cout << getYear();
}
extDateType(int month, int day, int year)
{
    dateType(month, day, year);
    updateMonthString();
}
void addDays(int x)
{
    dateType::addDays(x);
    updateMonthString();
}
};

int main()
{
    extDateType x(2, 25, 1996);
    x.addDays(10);
    x.printDateString();
    system("pause");
    return 0;
}

Simplified version of the base class

using namespace std;

#include <iostream>
#include <string>

class dateType
{
private:
    int dMonth;
    int dDay;
    int dYear;
    bool isLeapYear;
public:
    dateType(){}
    void addDays(int x)
    {
        int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

        dDay += x;
        for(int i = dMonth-1; dDay > days[i]; i++)
        {
            dDay -= days[i];
            dMonth++;
            if(dMonth == 13)
            {
                dMonth = 0;
                dYear++;
            }
            i = i % 11;
        }
    }
    dateType(int month, int day, int year)
    {
        isLeapYear = false;
        int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        if(month > 0 && month <= 12)
        {
            if(month == 2)
            {
                    if(year % 4 == 0)
                {
                    isLeapYear = true;
                    if(day > 0 && day <= 29)
                    {
                        dMonth = month;
                        dDay = day;
                        dYear = year;
                    }
                    else
                    {
                        cout << "Error" << endl;
                        dMonth = 1;
                        dDay = 1;
                        dYear = 2000;
                    }
                }
                else
                {
                    isLeapYear = false;
                    if(day > 0 && day <= 28)
                    {
                        dMonth = month;
                        dDay = day;
                        dYear = year;
                    }
                    else
                    {
                        cout << "Error" << endl;
                        dMonth = 1;
                        dDay = 1;
                        dYear = 2000;
                    }
                }
            }
            else
            {
                if(day > 0 && day <= days[month-1])
                {
                    dMonth = month;
                    dDay = day;
                    dYear = year;
                }
                else
                {
                    cout << "Error" << endl;
                        dMonth = 1;
                    dDay = 1;
                    dYear = 2000;
                }    
            }
        }
        else
        {
                cout << "Error" << endl;
            dMonth = 1;
            dDay = 1;
            dYear = 2000;
        }
    }
};

Using Visual Studio 2012. If anyone can help me figure out what the problem is, it would be greatly appreciated

Karthik T
  • 31,456
  • 5
  • 68
  • 87
gmaster
  • 692
  • 1
  • 10
  • 27
  • 2
    You're not overriding anything. – chris Jan 08 '13 at 02:39
  • @chris: addDays() I suppose? – Adrian Shum Jan 08 '13 at 02:55
  • 2
    @AdrianShum it isnt virtual, thats just function hiding. – Karthik T Jan 08 '13 at 02:57
  • @AdrianShum, I figured you meant for that one to be. I considered the possibility that you had others that were, but it didn't seem as likely. – chris Jan 08 '13 at 03:03
  • @KarthikT I think it is still overriding (I mean, he aimed to do so) but it is just not correctly done. However, for OP's case, even that's not a virtual method, it is the thing causing the problem, as OP is simply invoking the method directly on a child instance (instead thru a parent ref/pointer). – Adrian Shum Jan 08 '13 at 04:10
  • @AdrianShum yes I have added some information about the missconception in my answer. And that is not causing the problem, the crash is caused due to the line ` monthString = months[getMonth()];` in `UpdateMonthString` where `getMonth()` is an uninitialized junk value. – Karthik T Jan 08 '13 at 04:36

1 Answers1

5
extDateType(int month, int day, int year)
{
    dateType(month, day, year);

This is the fix to your problem, replace the above with the below.

extDateType(int month, int day, int year)
:dateType(month, day, year)
{

The former just creates a unused temporary object that is then destroyed after that line is executed, while the latter correctly calls base class constructor. This might have been more apparent if you had deleted the dateType(){} which would have resulted in a compiler error.

Since the base class constructor is not correctly called, when updateMonthString is called, the line monthString = months[getMonth()]; involves an array access to a large uninitialized junk value of month as an index. Thus the crash.

The latter syntax is called initialization lists is the correct way to initialize base classes and member objects which do not have a default (no args) constructor.

Also addDays would not work as you would expect in Java. You need to read up on the concept called Virtual Functions. By default all (non-static) functions are virtual in Java, but you need to manually make them virtual in C++ by doing the below

class dateType
{

    ...
    virtual void addDays(int x){
  //^^^^^^^
    ...

};
Community
  • 1
  • 1
Karthik T
  • 31,456
  • 5
  • 68
  • 87