Question

Why I can't access base class A's a member in class B initialization list?

   class A
    {
    public:
        explicit A(int a1):a(a1)
        {
        }
        explicit A()
        {
        }

    public:
        int a; 

    public:
        virtual int GetA()
        {
            return a;
        }
    };

    class B : public A
    {
    public:
        explicit B(int a1):a(a1) // wrong!, I have to write a = a1 in {}. or use A(a1)
        {
        }
        int GetA()
        {
            return a+1;
        }
    };

    class C : public A
    {
    public:
        explicit C(int a1):a(a1)
        {
        }
        int GetA()
        {
            return a-1;
        }
    };
Was it helpful?

Solution

A's constructor runs before B's, and, implicitly or explicitly, the former construct all of A's instance, including the a member. Therefore B cannot use a constructor on a, because that field is already constructed. The notation you're trying to use indicates exactly to use a constructor on a, and at that point it's just impossible.

OTHER TIPS

To build on Alex' answer, you can initialize the base class' "a" member by controlling its construction, like so:

class B : public A
{
public:
    explicit B(int a1) : A(a1) { }  // This initializes your inherited "a"
    ...
};

Note that I'm constructing the base class (capital "A") above, rather than attempting to directly initialize its inherited member (lowercase "a", drawing from your example).

To build even further on pilcrow's answer, you could easily initialize the A member like you want by overriding it in your B class:

class B : public A
{
public:
    int a; // override a

    explicit B(int a1) : a(a1) // works now
    {
    }

    ...
};

Though, I wouldn't necessarily recommend this ;)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top