再次出现错误 C2248

Again on error C2248

错误 C2248 在 Whosebug 上不是新出现的。不幸的是,我是使用 Boost 库的初学者,我无法修复代码中的错误:

// .h file

using namespace boost::interprocess;
using namespace std;

class CMsqQueueMngr {

public:
    // constructors & destructors
    CMsqQueueMngr();
    ~CMsqQueueMngr();

    int Open(char *queueName, int mode);
    int Close();
    int Read(uint8_t *data, int count);
    int Write(uint8_t *data, int count, int priority);

    boost::interprocess::message_queue mq;

private:
    std::string mqName;

};

// .cpp file

CMsqQueueMngr::CMsqQueueMngr()
{} **<=== ERROR C2248** 

CMsqQueueMngr::~CMsqQueueMngr()
{}

int CMsqQueueMngr::Open(char *queueName, int mode)
{
    try{
        //Erase previous message queue
        message_queue::remove(queueName);

        mqName.assign(queueName);

        //Create a message_queue.
        mq
            (create_only               //only create
            , queueName                 //name
            , 100                       //max message number
            , sizeof(int)               //max message size
            );  **<=== ERROR C2064 **


        //Send 100 numbers
        for (uint8_t i = 0; i < 100; ++i){
            mq.send(&i, sizeof(i), 0);
        }
    }
    catch (interprocess_exception &ex){
        std::cout << ex.what() << std::endl;
        return -1;
    }

    return 0;

}

编译器错误:

error C2248: 'boost::interprocess::message_queue_t>::message_queue_t': 无法访问在 class'boost::interprocess::message_queue_t>[= 中声明的私有成员11=]

error C2064: term 的计算结果不是带 4 个参数的函数

如何使变量 mq 可访问?

您必须在包含 class、

的构造函数中创建 message queue 对象 mq
CMsqQueueMngr::CMsqQueueMngr(): 
    mq(create_only, "my_first_queue_name", 100, sizeof(int)) 
{
}

并且您必须使用 initalizer list, because there is no accessible default constructor 作为消息队列对象(例如 mq)。这是构造函数右括号后编译器消息 C2248 的含义。

顺便说一句:成员永远不能在普通方法中初始化,这是编译器在您的 Open 方法中发现的错误(因此是 C2064)。其中还有一些其他错误(或误解,或开放式结局),而对 mq.send 的调用将按预期工作(至少一次)。


[更新]

或者,您可以使用堆栈上的变量访问 boost 的消息队列:

/// abbreviate name boost::interprocess::message_queue
using boost::interprocess::message_queue;

class CMsqQueueMngr {

public:
    CMsqQueueMngr(const std::string& queue_name);

    void WriteInt(int data);

    // (some methods omitted)

private:

    /// name of the queue
    std::string mqName;

};

CMsqQueueMngr::CMsqQueueMngr(const std::string& name):
    mqName(name)
{
}

void CMsqQueueMngr::WriteInt(const int data)
{
    // create a queue for max 100 values at first call, open if existing
    message_queue mq(open_or_create, mqName.c_str(), 100, sizeof (data));
    mq.send(&data, sizeof(data), 0);
}

...我没有尝试过,但如果不可能,the static remove method 就没有多大意义。

这里的错误意味着构造函数是私有的,因此不能被调用。此外,由于您没有显式调用它,默认构造函数作为 CMsqQueueMngr 的一部分被调用。由于它(可能)是有意私有的,因此您需要调用适当的构造函数或类似的东西,但您正试图以不打算使用的方式使用 class 。解决办法是研究说明。从这些,应该清楚该做什么,即通过初始化列表传递正确的参数:

CMsqQueueMngr::CMsqQueueMngr(char *queueName):
    mq(create_only, queueName, 100, sizeof (int))
{}

备注:

  • 由于代码现在只接收到构造函数的单个参数,因此您应该将其设为 explicit
  • 你不应该使用指向(非constchar的指针作为名字,使用std::string.
  • 总的来说,研究一下"const correctness"的思路。
  • 您必须向构造函数提供 queueName。如果你不想这样,你必须动态分配队列。
  • 作为替代方案,您可以在需要时创建消息队列的本地实例,但这听起来不是个好主意。您需要根据您的设计来决定。
  • 您的消息似乎是 uint8_t,那么为什么您的消息大小配置为 int 的大小?
  • 避免 "magic numbers" 喜欢 100。
  • int mode 也是一个糟糕的选择,如果这是应该的意思,请改用枚举。
  • 不要只捕获 return -1(另一个幻数)的异常。错误代码很糟糕,除非你真的处理它,否则就让异常飞吧。
  • 下次,正确缩进代码。毕竟,您希望人们阅读它,对吗?