【问题标题】:C++ Function call missing argument listC++ 函数调用缺少参数列表
【发布时间】:2013-06-18 04:46:00
【问题描述】:
#include <iostream>
#include <Windows.h>
#include <process.h>
#include <time.h>
#include <conio.h>

using namespace std;
class Klasa
{
public:
    void petla(void* Args)
    {
        time_t tWait = clock() + 4 * CLOCKS_PER_SEC;
        for(;;)
        {
            cout << "Test dzialania watkow" << endl;
            Sleep(1000);
        }
        _endthread();
    }
};
void main()
{
    Klasa* pKlasa = new Klasa;
    time_t tCzas = clock() + 10 * CLOCKS_PER_SEC;
    _beginthread(pKlasa->petla, 0, NULL);
    while(tCzas>=clock())
    {
        cout << " Dziala" << endl;
        Sleep(500);
    }
    getch();
}

错误 1 ​​错误 C3867: 'Klasa::petla': 函数调用缺少参数列表;使用 '&Klasa::petla' 创建指向成员 c:\users\bartek\documents\visual studio 2012\projects\wątki\wątki\source.cpp 26 1 Wątki

的指针

这是一个错误,我不知道该怎么办,因为我不能将 () 放入此 beginthread(pKlasa-&gt;petla, 0, NULL); 伙计们请帮助我:C

【问题讨论】:

  • 尝试将Klasa::petla设为静态,然后调用_beginthread(&Klasa::petla, 0, NULL);

标签: c++


【解决方案1】:

如果您希望Klasa::petla 成为线程的入口点,则需要将其声明为静态。

在对象中启动线程而不泄露对任何重要或线程危险的访问的典型习惯用法如下所示:

#include <iostream>
#include <Windows.h>
#include <process.h>
#include <time.h>

class Klasa
{
public:
    void Start();

private:
    static void ThreadEntry(void *p);
    void ThreadBody();
};

void Klasa::Start()
{
    _beginthread(Klasa::ThreadEntry, 0, this);
}

void Klasa::ThreadEntry(void *p)
{
    ((Klasa *) p)->ThreadBody();
    _endthread();
    return;
}

void Klasa::ThreadBody()
{
    // do threaded action here
    time_t tWait = clock() + 4 * CLOCKS_PER_SEC;
    for(;;)
    {
        cout << "Test dzialania watkow" << endl;
        Sleep(1000);
    }
}

void main()
{
    Klasa k;
    k.Start();

    time_t tCzas = clock() + 10 * CLOCKS_PER_SEC;
    while(tCzas>=clock())
    {
        cout << " Dziala" << endl;
        Sleep(500);
    }

    char c;
    c << std::cin; // stick to either cin/cout or C-style IO, not both
}

至少,我倾向于使用 pthread 来做到这一点。我想它与 Windows 线程基本相同。

另外,请尽量避免使用Hungarian Notation。这是个人喜好,但有很多不使用它的好论据(例如 C++ 是强类型的,每个变量或函数的类型从其定义中显而易见)。

【讨论】:

    【解决方案2】:

    来自documentation

    uintptr_t _beginthread( 
       void( *start_address )( void * ),
       unsigned stack_size,
       void *arglist 
    );
    

    所以该函数需要一个函数指针,而不是一个成员指针。您无法在两者之间进行转换。

    要么使用static 成员函数(绑定到类而不是实例),要么创建非成员函数。

    【讨论】:

    • 从技术上讲,成员函数仍然是函数。它基本上归结为这样一个事实,即非静态成员函数没有定义它们的类的实例就没有任何意义。尝试在没有对象的情况下调用它是没有意义的,并且由于 this 的隐式处理,编译器不会让你尝试。
    • @Wug 不要教我 C++。我知道这背后的原因,我只是不想使用错误或松散的措辞。
    • 您没有为自己发布此答案。我知道你知道 C++。其他读过这篇文章的人不会。
    【解决方案3】:

    你必须传递函数的地址。

    你不能写

    _beginthread(&(pKlasa->petla), 0, NULL);
    

    因为_beginthread 需要指向函数的指针,而不是指向对象方法的指针。 定义一个带有所需签名的普通函数:

    void threadfunc(void *data) {
      reinterpret_cast<Klasa*>(data)->petla();
    }
    

    然后开始一个新线程

    _beginthread(threadfunc, 0, pKlasa); 
    

    【讨论】:

    • 好吧,不管_beginthread 想要什么,&amp;(pKlasa-&gt;petla) 本身都是无效的。 C++ 不支持通过成员访问表达式获取指向成员的指针。获取成员指针的唯一方法是&amp;Klasa::petla
    【解决方案4】:
    std::thread(&Klasa::petla, pKlasa);
    

    如果您没有 C++11 库,您可以使用 Boost 执行相同操作。

    【讨论】:

      猜你喜欢
      • 2015-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多