如何处理C++98中不同类型的多个参数?

How to deal with multiple parameters of different types in C++98?

本文关键字:同类型 参数 何处理 处理 C++98      更新时间:2023-10-16

为了实现一个线程类(InC++98andWindows.h(。我有这样的东西:

Thread::Thread(_beginthreadex_proc_type fn)
{
m_raw = fn;
m_args = 0;
m_handle = 0;
m_id = 0;
}

上面的代码工作正常,它需要一个不接收参数的函数,并且在下一个代码中,它的函数由一个新线程调用:

void Thread::Join()
{
m_handle = (HANDLE)_beginthreadex(0, 0, m_raw, (m_args ? m_args : 0), 0, 0);
if (m_handle) WaitForSingleObject(m_handle, INFINITE);
}

此代码也适用于不带任何参数的函数。 现在我的问题是关于如何在 C++98 中在我的构造函数中接收可变参数并保存它们。,如果是这种情况,我不能使用现代 c++,我不需要帮助。所以请不要给我用 c++11 或更高版本实现的解决方案。

更新

现在我正在尝试一个 Java 风格的解决方案,因为每个线程都是一个 IRunnable,具有一个名为 Run 的纯虚拟函数。线程几乎是这个实现与差异,这是一个抽象类。通过这种方式,我可以避免参数,因为我不传递函数,而是编写另一个从 Thread 继承并实现 Run 的类。 代码如下所示:

界面

struct IRunnable
{
virtual void Run() = 0;
};

线程类

class Thread : public IRunnable
{
HANDLE m_handle;
DWORD  m_id;
typedef unsigned (__stdcall *Function)(void*);
_beginthreadex_proc_type m_raw;
void* m_args;
public:
Thread();
~Thread();
Thread(_beginthreadex_proc_type, void*);
Thread(_beginthreadex_proc_type);
unsigned GetId();
virtual void Run() = 0;
void Join();
unsigned int __stdcall call(void*);
};

仅调用是调用运行函数成员的包装器

unsigned int __stdcall Thread::call(void* data)
{
Run();
return 0;
}

我的问题在这里:

void Thread::Join()
{
m_handle = (HANDLE)_beginthreadex(0, 0, &this->call, 0, 0, 0);
if (m_handle) WaitForSingleObject(m_handle, INFINITE);
}

当我在vs2019中编译时,上面的代码会产生下一个错误:

error C2276: '&': illegal operation on bound member function expression

error C2660: '_beginthreadex': function does not take 5 arguments

对于您编辑的问题,您收到编译错误的原因是您尝试将地址发送到 Thread 对象的成员函数。不能获取指向成员函数的指针并在不保留对象指针的情况下使用它们。相反,您应该创建一个将 Thread* 作为其参数的全局函数,发送指向该函数的指针,并让它调用您的可运行对象。

unsigned thread_entry(void* thread_ptr)
{
Thread* thread = (Thread*) thread_ptr;
return thread->call();
}
void Thread::Join()
{
m_handle = (HANDLE)_beginthreadex(0, 0, thread_entry, this, 0, 0);
if (m_handle) WaitForSingleObject(m_handle, INFINITE);
}

附言通常,如果问题与您的问题明显不同,则最好提出新问题而不是编辑旧问题。

如果你查看几乎所有的线程库,它们很少支持发送多个参数;你通常发送一个指向某物的指针,如果你想要很多东西,你可以创建一个包含许多东西的结构并发送一个指向它的指针。

但是,如果你真的想要这个,你可以使用 C varargs 函数来迭代所有可变参数,并用它们分配一个链表,或者分配它们的数组,或者你想要的任何其他数据结构。然后,发送指向线程入口函数的指针。不过,您的函数仍然只接受一个指针。

在 C 语言中,没有简单的方法来构造一个va_list,这就是可变参数的发送方式。您不能只发送主线程上的va_list,因为当内存到达新线程时,内存将不处于活动状态。也没有扩展va_list以填充函数参数的好方法。

顺便说一句,我知道您正在使用C++,但就 C++98 而言,它的 varargs 支持与 C 基本相同,这就是我在答案中提到 C 的原因。