0

I've 2 classes (voluntary as simple as possible) and I'm working with Qt on Mac OS X:

//Class A
class A
{
protected:
    int getX(){return _x;};
private:
    int _x;
};

//Class B
class B : A
{
    void method(){qDebug() << this->getX();}
};

And the compiler throws:

error: 'getX' is a private member of 'A'

Am I missing something? I've tried with:

qDebug() << this->A::getX();

Which doesn't work either!

Jens
  • 69,818
  • 15
  • 125
  • 179
Thomas Ayoub
  • 29,063
  • 15
  • 95
  • 142
  • It seems like you forgot `public` in `class B: **public A**`. – aldeb May 30 '13 at 08:54
  • 4
    Come on, post a **real code**! Your snippet doesn't even compile! – gx_ May 30 '13 at 08:58
  • I wont post 200 useless lines for a question that get 5 answer within 3 minutes... – Thomas Ayoub May 30 '13 at 09:10
  • @gx_ It doesn't compile and he asks _why_ it isn't and how he can fix it. – Daniel Daranas May 30 '13 at 09:31
  • 1
    @Daniel It doesn't compile because of _other_ errors than "'getX' is a private member of 'A'": `int getX(){return _x};` should be `int getX(){return _x;}`, `this.getX()` should be `this->getX()` (OP edited afterwards), and both class definitions miss a semicolon after the closing brace. And after those corrections (and replacing `qDebug()` with `cout` or whatever you can include), the code compiles and does _not_ give the quoted error. – gx_ May 30 '13 at 10:03
  • (can't edit) BTW, it means that the answers below telling to use `: public A` instead of `: A`, although well-advised, are irrelevant _to the given snippet_... That's why I asked for a "real" code, even if simplified and snipped out, but at least that gives the _same_ error as declared, so that the OP can receive accurate solutions. – gx_ May 30 '13 at 10:14
  • @gx_ Well spotted. Answerers seem to have skimmed the OP's code and second guessed that his function visibility problem was due to its inheriting implicitly as private. That was my guess, too. – Daniel Daranas May 30 '13 at 13:54

6 Answers6

6

When you don't specify the type of inheritance the default is taken as private.

In private inheritance,

Base Class' public members are private.

From standard docs, 11.2.2

In the absence of an access-specifier for a base class, public is assumed when the derived class is defined with the class-key struct and private is assumed when the class is defined with the class-key class.

Community
  • 1
  • 1
Suvarna Pattayil
  • 5,136
  • 5
  • 32
  • 59
4

there are three types of inheritance:

  1. public
  2. protected
  3. private

the dafult mode for class is private, and for struct it is public:

In the absence of an access-specifier for a base class, public is assumed when the derived class is defined with the class-key struct and private is assumed when the class is defined with the class-key class.

                                                   [From C++ standard, 11.2.2]

So, when you say:

class B: A

this is private inheritance and thus all public and protected members of a base class will be inherited as private. What you need is

class B: public A

or

class B: protected A

Private and protected inheritance is used more often where defining implementation details. Private bases are most useful when defining a class by restricting the interface to a base so that stronger guarantees can be provided. For example, Vec adds range checking to its private base vector (§3.7.1) and the list of pointers template adds type checking to its list<void*> base -> see Stroustrup ("C++..." §13.5).

Example:

//Class A
class A
{
public:
    int getX(){return _x;};
protected:
    int getX2(){return _x;}
private:
    int _x;
};

//Class B
class B : protected A  //A::getX and A::getX2 are not visible in B interface,
          ^^^^^^^^^    // but still we can use it inside B class: inherited
                       // members are always there, the inheritance mode
                       // affects only how they are accessible outside the class
                       // in particular for a children
{
public:
    int method(){ return this->getX();}
    int method2(){ return this->getX2();}
};

int main(int argc, char** argv) {

    B b=B();
    printf("b.getX(): %d",b.method());  // OK
    printf("b.getX(): %d",b.method2()); // OK

    return 0;
}

Further effects to inheritance

Additionally, when you declare class as

class B: A

being the same as class B: private A further inheritance becomes unavailable: only class that derives from A and its friends can use A public and protected members. Only friends and members of B can convert B* to A*.

If A is a protected base then its public and protected members can be used by class B and its friends and by classes derived from B and their friends. Only friends and members of B and friends and members of class derived from B can convert B* to A*.

If A is a public base finally, then its public members can be used by any class and its protected members can be used by derived classes and their friends and by classes derived from B and their friends. Any function can convert B* to A*.

Note also that you cannot cast constness with dynamic_cast or static_cast, it is said that they both respect constness. They both respect access controls also (it is not possible to cast to a private base [because only derived class methods might do Derived* -> Base* and methods of classes being friends to this {friend declaration is in Base}])

more in Stroustrup ("C++", 15.3.2)

4pie0
  • 29,204
  • 9
  • 82
  • 118
3

When you inherit a class from another, the mode of inheritance should be mentioned. So, you have to declare as

class B: public A

Then you won't have the error

Aswin Murugesh
  • 10,831
  • 10
  • 40
  • 69
1

Your code should be as follows:

class A {
    protected:
        int getX() { return _x; }

    private:
        int _x;
};

//Class B
class B : public A  {
    void method() { this->getX(); }
};

They were many errors:

  • class B: public A;
  • this->getX();
  • commas after class declarations
aldeb
  • 6,588
  • 5
  • 25
  • 48
1

Try this:

//Class A
class A
{
protected:
    int getX(){return _x};
private:
    int _x;
};

//Class B
class B : public A
{
    void method(){qDebug() << this->getX();}
};

You forgot the keyword public, you don't use this as a pointer and you forgot the ; at the end of the classes.

nouney
  • 4,363
  • 19
  • 31
0

You forgot ; in your getter return

int getX() { return _x; };
Jackyto
  • 1,569
  • 3
  • 15
  • 33