简体   繁体   中英

Can a pure virtual function be called by an accessor function?

If my pure virtual function is ie

virtual string func()=0;

is it returnable to an accessor function?

Edit: I apologize for earlier confusion, so I am adding a sample code

class Parent{
  public:
   parent(void){};
   virtual string func()=0;
   string getFunc (void) const{return var=func();} ;
  protected: 
   string var;
}
class Child: public  Parent{

public:
 class Child(void); 

string func(){
 string random // this is very generic I actually pretend 
               //to do some math here and return a string
 return random}; 

My intent is to then use the instantiated child object and ask the accessor(getFunc()) to return a value, that I can only compute based on the func(). But the error states that the nature of virtual function does not allow return, which frankly i find weird because it does have the return tag on it.

Calling a pure virtual function in another member function shouldn't be a problem at all. (Unfortunately, OP didn't copy/paste the exact error message.)

The exposed sample of OP has unfortunately a lot of typos, syntax errors, and other weaknesses.

Fixing this, I found one essential issue: the const -ness of Parent::getFunc() .

Parent::getFunc() calls a non-const member function and mutates the member variable this->var which is not accepted by the compiler.

Removing the const , it worked.

Fixed sample:

#include <iostream>
#include <string>

class Parent{
  public:
    Parent() = default;

    virtual std::string func() = 0; // PURE VIRTUAL

    std::string getFunc() // WRONG: const
    {
      return var = func();
    }

  protected: 
    std::string var;
};

class Child: public Parent {

  public:
    Child() = default; 

    virtual std::string func() override
    {
      std::string random; // this is very generic I actually pretend 
               //to do some math here and return a string
      return random;
    }
};

#define DEBUG(...) std::cout << #__VA_ARGS__ << ";\n"; __VA_ARGS__ 

int main()
{
  DEBUG(Child child);
  DEBUG(child.getFunc());
}

Output:

Child child;
child.getFunc();

Live Demo on coliru


Though, a const accessor (I would call it “getter”) seems reasonable. With a little bit more re-design, it can be achieved as well:

#include <iostream>
#include <string>

class Parent{
  public:
    Parent() = default;

    virtual std::string func() const = 0; // PURE VIRTUAL

    std::string getFunc() const
    {
      return var = func();
    }

  protected: 
    mutable std::string var;
};

class Child: public Parent {

  public:
    Child() = default; 

    virtual std::string func() const override
    {
      std::string random; // this is very generic I actually pretend 
               //to do some math here and return a string
      return random;
    }
};

#define DEBUG(...) std::cout << #__VA_ARGS__ << ";\n"; __VA_ARGS__ 

int main()
{
  DEBUG(Child child);
  DEBUG(child.getFunc());
}

Output: the same like above

Live Demo on coliru

Note:

  1. I made the virtual func() const to make it accessable for const instances / member functions.

  2. The member variable became mutable to make it writable in const member functions.

I must admit that I personally find the mutable a bit scaring. In my simple mind, something is const or it isn't. However, the mutable just seems to be invented for update of internal caching of actually const objects. So, it might be the right tool here. (It's a little bit hard to say without more context.)

More about mutable :mutable specifier

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