【问题标题】:Again on error C2248再次出现错误 C2248
【发布时间】:2015-04-01 07:33:29
【问题描述】:

错误 C2248 在 stackoverflow 上不是新的。不幸的是,我是使用 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;

}

编译器错误:

错误 C2248:'boost::interprocess::message_queue_t>::message_queue_t':无法访问在类'boost::interprocess::message_queue_t 中声明的私有成员>

错误 C2064:术语不计算为采用 4 个参数的函数

如何使变量 mq 可访问?

【问题讨论】:

  • 除非您真的想得到一些更令人困惑的错误,否则我建议您从标题中删除 using namespace 语句。
  • 您应该仔细查看构造函数和初始化列表,以了解编译器在说什么。我试着用我的answer 来关注这个。
  • ...不是变量 mq 不可访问。
  • @pmr:在头文件中声明了类 CMsqQueueMngr。如果我删除“using namespace boost::interprocess”语句,编译器会指示错误:“error C2065: 'create_only': identificatore non dichiarato”
  • @cris1967 是的,您必须限定此标识符。 boost::interprocess::create_only

标签: c++ boost compiler-errors message-queue boost-interprocess


【解决方案1】:

您必须在包含类的构造函数中创建message queue 对象mq

CMsqQueueMngr::CMsqQueueMngr(): 
    mq(create_only, "my_first_queue_name", 100, sizeof(int)) 
{
}

您必须使用initalizer list 来执行此操作,因为消息队列对象(如mq无法访问default constructor。这就是编译器在构造函数右大括号后的消息 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 将没有多大意义。

【讨论】:

  • 我实际上是这样使用Ulrich(见上文)提出的解决方案:
  • CMsqQueueMngr(char *queueName) : mq(create_only, queueName, 100, sizeof(int)){ mqName.assign(queueName);
  • 初始化列表绝对是解决方案。我想知道:是否可以为 mq 创建一个(默认)构造函数作为替代方案?
  • @cris1967 我添加了一个不使用消息队列成员的替代方法
【解决方案2】:

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

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

注意事项:

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

【讨论】:

  • 非常感谢 Ulrich 提供的详尽解决方案。
  • 非常感谢 Ulrich 提供详尽的解决方案。也谢谢你的笔记。我附加的代码只是一个快速示例,类似于我正在工作的代码。为了加快速度,我加入了幻数和其他不精确性。无论如何,你的观察是绝对正确的。看来我不能投票,因为我没有足够的声誉。
  • @cris1967 您可以尝试改善您的问题以获得声誉。但是接受你的问题的答案应该总是有效的(所以你会得到另外 2 分)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多