user318904
user318904

Reputation: 3066

Is this c++ inheritance structure possible?

I have not programmed in c++ in a long time and want some simple behavior that no amount of virtual keywords has yet to produce:

class Base {
  public:
    int both() { return a(); }
};

class Derived : public Base {
  protected:
    int a();
};

class Problem : public Derived {
};

Problem* p = new Problem();
p.both();

Which gives me a compile-time error. Is this sort of behavior possible with c++? Do I just need forward declaration? Virtual keywords on everything?

Upvotes: 1

Views: 161

Answers (6)

Martin Gunia
Martin Gunia

Reputation: 1141

As others point out, you need to declare a() as pure virtual method of Base and change access to public to make your snippet work.

Here is another approach possible in c++: instead of virtual functions, you can use static polymorphism via the Curiously recurring template pattern:

template <class D>
class Base : public D
{
public: 
    int both() { return D::a(); }
};

class Derived : public Base<Derived> 
{
public:
    int a();
};

I'm posting this approach since you're asking what is possible in c++. In practice, virtual methods are most often a better choice because of their flexibility.

Upvotes: 1

Matthieu
Matthieu

Reputation: 4620

You have multiple problems in your code :

  • unless you declare them public or protected, elements of a class are private as a default.
  • you need a virtual keyword to define a virtual function that would be callable in a parent.
  • new returns a pointer to Problem.

Here's a complete working code based on your test :

class Base { 
protected:
virtual int a()=0;
public:
    int both() { 
        return a(); 
    } 
}; 

class Derived : public Base { 
private :
int a()
{
printf("passing through a!");
return 0;
}


}; 

class Problem : public Derived { 
}; 

int main(void)
{
  Problem* p = new Problem(); 
  p->both();
}

tested on CodePad.

Upvotes: 1

Tom
Tom

Reputation: 45104

You should declare the a() function as a pure virtual method in the Base class.

class Base {
    int both() {
        return a();
    }

    virtual int a()=0;
};

Then implement the a() method in the Derived class

class Derived : public Base {
    int a(){/*some code here*/}
};

And finally, Problem class doesn't see the both() method, since its private in Base. Make it public.

class Base {
public:
    int both() {
        return a();
    }
};

Upvotes: 4

Eran Zimmerman Gonen
Eran Zimmerman Gonen

Reputation: 4507

You need a() to be declared in class Base, otherwise the compiler doesn't know what to do with it.

Also, both() is currently a private method (that's the default for classes), and should be made public in order to call it from main.

Upvotes: 2

Greg Hewgill
Greg Hewgill

Reputation: 992965

Your function both() is private by default. Try:

class Base {
public:
    int both() {
        // ...

(In the future, it would be helpful if you tell us what the actual error message was.)

Upvotes: 3

Daniel A. White
Daniel A. White

Reputation: 190925

No. You will have to use a pure virtual a in base.

class Base {
    virtual int a() = 0;
    int both() {
        return a();
    }
};

Upvotes: 4

Related Questions