简体   繁体   中英

Accessing protected member in base class from a derived class

I have the following snippet of code:

const int DATE_LENGTH = 6;

class BaseClass {
    protected:
        int date[DATE_LENGTH];
        int year;
    public:
        BaseClass(){}
        BaseClass(int *d) {
            for (int i = 0; i < DATE_LENGTH; i++) { date[i] = d[i];}
            year = 1900 + date[4] * 10 + date[5];
        }
        void printYear() {
            cout << year << endl;
        }
};

class DerivedClass : public BaseClass {
    public:
        DerivedClass() {}
        void printYear() {
            cout << year << endl;
        }
};

int main(int argc, char *argv[]) {
    int dob[] = {1, 6, 1, 0, 9, 0};
    BaseClass base(dob);
    base.printYear(); // prints 1990

    DerivedClass derived;
    derived.printYear(); // prints 1439156608
}

I'm having trouble understanding why the output from printYear() in my derived class is outputting junk. Am I missing something very obvious?

Any help would be appreciated!

Your program has undefined behaviour. The default constructor of DerivedClass , which you are using, does not initialize the year member.

If you wanted to initialize the base member, you could do that by calling an appropriate base constructor, or by assigning the value directly.

DerivedClass() { year = 1999; }

The default constructor of class BaseClass

BaseClass(){}

does not initislize data members date and year

This default constructor is called by the default constructor of class DerivedClass when you create object derived

DerivedClass derived;

So these data members have arbitrary values and your program has undefined behaviour.

Change the derived class the following way

class DerivedClass : public BaseClass {
    public:
        using BaseClass::BaseClass;
        DerivedClass() {}
        void printYear() {
            cout << year << endl;
        }
};

and create object derived as

DerivedClass derived( dob );

Or instead of the using declaration you can yourself explicitly define a constructor in class DerivedClass that has one parameter of type int * and calls the corresponding constructor of the base class. For example

class DerivedClass : public BaseClass {
    public:
        DerivedClass() {}
        DerivedClass( int *d ) : BaseClass( d ) {}
        void printYear() {
            cout << year << endl;
        }
};

The other provided answers only deal with part of the issue, partly because the date itself is never defined in the DerivedClass default constructor of either currently provided, and the other part being the BaseClass default constructor still has no defined value for either class variable (date or year). If the following code is used, depending what the default date and year should be, no additional change is actually required for the DerivedClass.

#include <iostream>

using namespace std;

const int DATE_LENGTH = 6;

class BaseClass {
    protected:
        int date[DATE_LENGTH];
        int year;
    public:
        BaseClass()
        {
            int date[] = {1, 6, 1, 0, 9, 0};
            year = 1900 + date[4] * 10 + date[5];
        }
        BaseClass(int *d)
        {
            for (int i = 0; i < DATE_LENGTH; i++) { date[i] = d[i];}
            year = 1900 + date[4] * 10 + date[5];
        }
        void printYear() {
            cout << year << endl;
        }
};

class DerivedClass : public BaseClass {
    public:
        DerivedClass() {}
        void printYear() {
            cout << year << endl;
        }
};

int main(int argc, char *argv[])
{
    int dob[] = {1, 6, 1, 0, 9, 0};
    BaseClass base(dob);
    base.printYear(); // prints 1990

    DerivedClass derived;
    derived.printYear(); // prints 1439156608
    return 0;
}

Application Output

1990
1990

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM