Ramakrishnan Kannan
Ramakrishnan Kannan

Reputation: 624

C++ abstract class inheritance virtual function

I have an abstract base class with some attributes or member elements and some public functions and a public pure virtual functions. In the derived class of the abstract class, I want to (a) access the members of the abstract base class as private members and (b) the public functions and defined pure virtual functions stay as public. Is there a way to do it? That is., what should be the xxxx of AbstractBase and yyyy access specifier in the derived to realize this?

#include <iostream>

class AbstractBase {
 xxxx: <-- // protected/private/public?
  std::string baseprivate1;

 public:
  virtual void set_privates() = 0;
  void print() { std::cout << baseprivate1 << std::endl; }
  void foo() { // some definition here }
};

class Derived : yyyy AbstractBase {  <--- //public/protected/private? 
 private:
  std::string derivedprivate1;

 public:
  void set_privates() {
    // I want this baseprivate1 to be private in derived class as well.
    // When I choose xxxx as protected and yyyy as public, the baseprivate1 is protected. 
    this->baseprivate1 = "Base private1";
    this->derivedprivate1 = "Derived private1";
  }
  void print() {
    AbstractBase::print();
    std::cout << this->derivedprivate1;
  }
  // When I choose xxxx as protected and yyyy as protected
  // foo becomes protected and unable to call from outside
  // I want the foo of abstract base to be public here as well. 
};

int main(int argc, char *argv[]){
    Derived d;
    d.set_privates();
    d.print();
    d.foo(); // I should be able to call foo of abstract base class
}

It can be confused as duplicate of Difference between private, public, and protected inheritance. If you keep xxxx as protected and yyyy as public, then baseprivate1 will be protected in Derived and is not private anymore. Alternatively, if xxxx is public/protected and yyyy is private, the functions in derived becomes private.

Upvotes: 0

Views: 441

Answers (1)

Jeff
Jeff

Reputation: 110

One way to acomplish what you want would be to use private inheritance of AbstractBase on your Derived class. You can then expose some of AbstractBase's methods with a using-declaration under a public access specifier in the Derived class.

#include <iostream>

class AbstractBase {
    public:
        std::string baseprivate1;

        virtual void set_privates() = 0;
        void print() { std::cout << baseprivate1 << std::endl; }
        void foo() { /* some definition here */ }
};

class Derived : private AbstractBase { // use private inheritance on AbstractBase
    private:
        std::string derivedprivate1;

    public:
        // expose AbstractBase's methods with using-declarations
        using AbstractBase::foo;
        using AbstractBase::print;

        void set_privates() {
            this->baseprivate1 = "Base private1";
            this->derivedprivate1 = "Derived private1";
        }

        void print() {
            AbstractBase::print();
            std::cout << this->derivedprivate1 << std::endl;;
        }
};

int main(int argc, char *argv[]){
    Derived d;
    d.set_privates();
    d.print();
    d.foo();
    return 0;
}

Upvotes: 1

Related Questions