首页 > 解决方案 > C++ 受保护的函数在派生类中不可见

问题描述

我正在尝试调用在 LexContext 中声明为纯虚拟的 initCapture()。我试图通过覆盖它的 StaticLexContext 在 ArduinoLexContext 中间接调用它。

我明白了

LexContext.hpp:316:25: error: there are no arguments to 'initCapture' that depend on a template parameter, so a declaration of 'initCapture' must be available [-fpermissive]

这是代码。我省略了大部分 LexContext,因为它在这里不相关。我整个早上都在做这件事,我知道答案正盯着我看,但我需要另一双眼睛。

提前致谢。

#include <cstdint>
#include <ctype.h>
#include <stdlib.h>
namespace lex {
  // represents a cursor and capture buffer over an input source
  class LexContext {
      int16_t _current;
      unsigned long int _line;
      unsigned long int _column;
      unsigned long long _position;
    protected:
      // reads a character from the underlying device
      // read() should return EndOfInput if no more data is available,
      // and Closed if the underlying source has been closed, where
      // applicable
      virtual int16_t read()=0;
      // called to initialize the capture buffer
      virtual void initCapture()=0;
    public:
      ...

  };
// represents a LexContext with a fixed size buffer
  template<const size_t S> class StaticLexContext : virtual public LexContext {
    char _capture[S];
    size_t _captureCount;
    protected:
      // initializes the capture buffer
      void initCapture() override {
        *_capture=0;
        _captureCount=0;

      }
    public:
      StaticLexContext() {
            
      }
      // the capacity of the capture buffer (not including the trailing NULL)
      size_t captureCapacity() override { return S-1; }
      // the count of characters in the capture buffer
      size_t captureCount() const override {return _captureCount;}
      // returns a pointer to the capture buffer
      char* captureBuffer() override {return _capture;}
      // clears the capture buffer
      void clearCapture() override {
        _captureCount = 0;
        *_capture=0;
      }
      // captures the character under the cursor if any
      // returns true if a character was captured.
      bool capture() override {
        if (Closed!=current() && EndOfInput != current() && BeforeInput != current() && (S - 1) > _captureCount)
        {
          _capture[_captureCount++] = (uint8_t)current();
          _capture[_captureCount] = 0;
          return true;
        }
        return false;
      }

  };
#ifdef ARDUINO
  // represents a fixed length LexContext for the Arduino built on the Arduino SDK's Stream class
  template<const size_t S> class ArduinoLexContext : public StaticLexContext<S> { 
        Stream* _pstream;
    protected:
        // reads a character from the stream
        int16_t read() override {
            if(!_pstream)
              return LexContext::Closed;
            return _pstream->read();
        }
    public:
      ArduinoLexContext() {
            
      }
        // initializes the lexcontext with a stream
        bool begin(Stream& stream) {
            _pstream = &stream;
            initCapture(); // compile error!
            return true;
        }
    };
#endif
}

标签: c++11inheritanceprotected

解决方案


伙计们,Raymond Chen 在评论中。他是个英雄。

问题不在于受保护。问题是 ArduinoLexContext 派生自模板类。编译器看到 initCapture(); 并说:“这是从基类派生的成员函数吗?还是全局函数?我假设它是全局函数。错误:没有名为 initCapture 的全局函数。” (可能有一个特化模板<> StaticLexContext<0> { /* 不是从 LexContext 派生的,没有 initCapture 方法 */ }。)您需要帮助编译器并编写 this->initCapture() 来表示“The initCapture 方法来自我的基类,相信我。”

– 雷蒙德陈


推荐阅读