【问题标题】:Virtual protected function error虚拟保护功能错误
【发布时间】:2011-06-17 07:05:51
【问题描述】:

我有 Packet 类包含虚方法,我有 LogInRequest 类扩展了数据包类

Packet.h 文件

class Packet {

public:
    Packet();
    virtual ~Packet();

protected:
    virtual char* toByte() = 0;
    virtual void fromByte(char *d) = 0;
    virtual Packet* handle() = 0;

    short m_bodySize;
    int64_t m_deviceId;
};


/*
 * LogInRequestPacket
 */
class LogInRequestPacket: public Packet{

public:

    LogInRequestPacket();
    virtual ~LogInRequestPacket();

    virtual char* toByte();
    virtual void fromByte(char *d);
    virtual Packet* handle();
};

Packet.cpp 文件

#include "Packet.h"

Packet::Packet() {
    // TODO Auto-generated constructor stub

}

Packet::~Packet() {
    // TODO Auto-generated destructor stub
}

/*
 * LogInRequestPacket
 */
LogInRequestPacket::LogInRequestPacket(){
    printf("LogInRequestPacket is being created... \n");
}

LogInRequestPacket::~LogInRequestPacket(){

}

char* LogInRequestPacket::toByte(){

}

void LogInRequestPacket::fromByte(char *d){

}

Packet* LogInRequestPacket::handle(){

}

我正在尝试像这样从工厂创建这个 LogInRequestPacket

Packet *packet = m_packetFactory->createInstance(static_cast<PACKET_TYPES>(type));
packet->fromByte(pdata);

而且似乎是在尝试调用受保护的虚拟 fromByte 函数,而不是子类的 fromByte 函数。

我在 Packet.h 文件的 Packet 类范围内声明“virtual void fromByte(char *d) = 0”的那一行出现一条红线,它抱怨“...受保护”

此外,它在上下文中也抱怨 x

packet->fromByte(pdata);

我该如何解决这个问题。提前谢谢...

【问题讨论】:

    标签: c++


    【解决方案1】:

    当你尝试通过指针或引用调用方法时,编译器会在对象的 static 类型中验证函数的访问说明符,即使它会将调用分派到动态类型。

    在您的Packet 类中,您已声明您不希望用户代码(Packet、朋友和派生类除外)能够调用这些方法,而编译器只是告诉您这一点。如果这些函数应该可以从其他代码访问,请将它们公开:

    class Packet {
    public:
        Packet();
        virtual ~Packet();
    
        virtual char* toByte() = 0;
        virtual void fromByte(char *d) = 0;
        virtual Packet* handle() = 0;
    protected:
        short m_bodySize;
        int64_t m_deviceId;
    };
    

    【讨论】:

      【解决方案2】:

      被调用函数访问说明符总是在编译时从调用对象/指针/引用推导出来的

      如果基 class(在您的情况下)正在调用该函数,则编译器将考虑其访问说明符,即 protected,因此会出现错误。

      假设,您在基类中设置方法访问说明符public,在派生类中设置protected,并运行相同的代码。它可以正常工作(这与 C++ 中的 Java 访问说明符不同)。

      【讨论】:

        【解决方案3】:

        packet 被声明为Packet*。由于在 Packet 中它不是公开的 - 你不能这样做。

        一般来说,我认为在继承时更改接口函数的访问权限并不是一个好主意。如果隐藏了某个功能 - 可能是有原因的。如果没有 - 更改父对象。

        【讨论】:

          猜你喜欢
          • 2011-11-15
          • 2016-09-26
          • 1970-01-01
          • 1970-01-01
          • 2011-06-01
          • 2014-05-12
          • 1970-01-01
          • 1970-01-01
          • 2017-08-01
          相关资源
          最近更新 更多