如何使用不同的线程访问Singleton类成员函数?

时间:2017-09-18 17:08:31

标签: c++ oop c++11 design-patterns

我正在尝试使用单例实例在不同的线程上运行print()和print(char ch)方法。

任何人都可以帮助我解决为什么我会收到错误: -

错误C3867:'Singleton :: print':函数调用缺少参数列表;使用'& Singleton :: print'创建指向成员的指针

错误C3867:'Singleton :: print':函数调用缺少参数列表;使用'& Singleton :: print'创建指向成员的指针

错误C2661:'std :: thread :: thread':没有重载函数需要2个参数

还帮我纠正以下代码。

class Singleton
{
private:
    Singleton()
    {}
    static Singleton* singletonInstance;
public:
    static Singleton* getSingletonInstance();
    void print()
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
        for (int i = 0; i < 100000; i++)
        {
            cout<<i<<endl;
        }
    }
    void print(char ch)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
        for (int i = 0; i < 100000; i++)
        {
            cout<<ch<<" "<<i<<endl;
        }
    }
};
Singleton* Singleton::singletonInstance = nullptr;
Singleton* Singleton::getSingletonInstance()
{
    if(!singletonInstance)
        singletonInstance=new Singleton();

    return singletonInstance;
}

int main()
{
    std::thread t1(Singleton::getSingletonInstance()->print);
    std::thread t2(Singleton::getSingletonInstance()->print,'T');
    t1.join();
    t2.join();
    return 0;
}

2 个答案:

答案 0 :(得分:5)

发布的代码有两个问题:

1-将函数指针传递给线程的方式是错误的:

std::thread t1(Singleton::getSingletonInstance()->print);

并且编译器正在抱怨并给你一个提示你如何将函数指针传递给线程。它说: 使用'&amp; Singleton :: print'创建指向成员的指针

同样,step1必须按以下方式传递函数指针:

std::thread t1(&Singleton::print);

Step2:设置Sigleton类的对象,函数指针属于。

std::thread t1(&Singleton::print, Singleton::getSingletonInstance());

但是只有在你没有重载函数打印时才会起作用,因为编译器无法找到,你愿意打电话给哪个打印。

现在我们又遇到了第二个问题:如何解决重载函数的问题?

你有两种可能性:

1-你告诉编译器有关你想要调用哪个函数的帮助:

int main()
{
    using print1 = void (Singleton::*)();
    using print2 = void (Singleton::*)(char);
    std::thread t1(print1(&Singleton::print), Singleton::getSingletonInstance());
    std::thread t2(print2(&Singleton::print), Singleton::getSingletonInstance(), 'T');
    t1.join();
    t2.join();
    return 0;
}

2-你使用lambda函数并直接调用函数:

int main()
{
    auto *s = Singleton::getSingletonInstance();
    std::thread t1([&s](){s->print();});
    std::thread t2([&s]() {s->print('T');});
    t1.join();
    t2.join();
    return 0;
}

第二个更聪明,更容易理解

答案 1 :(得分:2)

首先,你在线程中调用错误的函数。您需要传递成员函数print地址,然后是指向单例的指针 - 然后是参数(如果有的话)。

std::thread(&Singleton::print, Singleton::getSingletonInstance());

其次,因为您正在调用重载函数,所以您需要 成员函数的地址转换为正确的重载类型。

// call the char version
std::thread(static_cast<void(Singleton::*)(char)>(&Singleton::print), Singleton::getSingletonInstance(), 'T');

这样的事情:

class Singleton
{
private:
    Singleton()
    {}
    static Singleton* singletonInstance;
public:
    static Singleton* getSingletonInstance();
    void print()
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
        for (int i = 0; i < 100000; i++)
        {
            cout<<i<<endl;
        }
    }
    void print(char ch)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
        for (int i = 0; i < 100000; i++)
        {
            cout<<ch<<" "<<i<<endl;
        }
    }
};
Singleton* Singleton::singletonInstance = nullptr;
Singleton* Singleton::getSingletonInstance()
{
    if(!singletonInstance)
        singletonInstance=new Singleton();

    return singletonInstance;
}

int main()
{
    std::thread t1(static_cast<void(Singleton::*)()>(&Singleton::print), Singleton::getSingletonInstance());
    std::thread t2(static_cast<void(Singleton::*)(char)>(&Singleton::print), Singleton::getSingletonInstance(), 'T');
    t1.join();
    t2.join();
    return 0;
}

或者你可以通过lambda expression来调用你的单身人士的功能,这实际上让事情变得更容易:

std::thread t1([]{Singleton::getSingletonInstance()->print();});
std::thread t2([]{Singleton::getSingletonInstance()->print('T');});

请参阅Lambda Expressions