gpt4 book ai didi

c++ - 未解析的外部符号(构造函数)

转载 作者:搜寻专家 更新时间:2023-10-31 01:05:33 24 4
gpt4 key购买 nike

在建筑中,我得到以下错误:

main.obj : error LNK2019: unresolved external symbol ""public: __cdecl Worker::Worker(void)" (??0Worker@@QEAA@XZ)" in function "main".

main.obj : error LNK2019: unresolved external symbol ""public: virtual __cdecl Worker::~Worker(void)" (??1Worker@@UEAA@XZ)" in function "main".


我找不到问题。 (我也看了 here)
main.cpp
#include <iostream>
#include <thread>
#include "worker.h"

using namespace std;

void pause_thread(int n)
{
std::this_thread::sleep_for (std::chrono::seconds(n));
std::cout << "pause of " << n << " seconds ended\n";
}

int main()
{
std::cout << "Spawning and detaching 3 threads...\n";
std::thread (pause_thread,1).detach();
std::thread (pause_thread,2).detach();
std::thread (pause_thread,3).detach();
std::cout << "Done spawning threads.\n";

std::cout << "(the main thread will now pause for 5 seconds)\n";
// give the detached threads time to finish (but not guaranteed!):
pause_thread(5);

Worker w;



return 0;
}
worker.h
#ifndef WORKER_H
#define WORKER_H


#include "jobqueue.h"
#include "job.h"
#include <mutex>
#include <thread>

using namespace std;

class Worker
{
private:
JobQueue jobs;
mutex mu;
thread & workerThread;
bool stop;

void work();

public:
Worker();
virtual ~Worker();
void addJob(Job*);
int getJobCount();


};

#endif // WORKER_H
worker.cpp
#include "worker.h"

Worker::Worker(): workerThread(work), stop(false)
{
}

Worker::~Worker()
{
workerThread.join();
}

void Worker::work(){
while (!stop) {
unique_lock<mutex> lock(mu, defer_lock);
lock.lock();
Job* job = jobs.getNextJob();
lock.unlock();

job->run();
delete job;
}
}

void Worker::addJob(Job* job){
jobs.append(job);
}

int Worker::getJobCount(){
unique_lock<mutex> lock(mu);
return jobs.size();
}
project.pro
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt

SOURCES += main.cpp \
jobqueue.cpp \
worker.cpp

HEADERS += \
jobqueue.h \
worker.h \
job.h
删除Project.pro.user可解决(main-)问题,现在再次显示错误

最佳答案

您的代码中有很多错误,正如我建议您在此之前应该学习更多的C++基础知识。
当我在评论中显示错误时,让我仅使用成员函数来回答您的问题:

与Java相对,C++将函数视为一等公民(Java 8改进解决了一些问题,但也没有将函数视为一等公民)。
C++将函数理解为可调用实体的概念:可调用实体是可以被调用的任何东西,即被视为函数。因此,可调用实体可以是:

  • 全局函数:就是很好的旧C函数。可以定义,实现和调用它:
    void f() {}

    int main()
    {
    f(); //Call to f
    }
  • 成员函数:经典的OO成员函数。它在一个对象内调用,并对其数据进行操作:
    struct foo
    {
    void f();
    };

    int main()
    {
    foo myfoo;

    myfoo.f(); //Call to foo::f
    }
  • 静态成员函数:它是一个未链接到对象的成员函数,它在类级别运行,因此的签名与全局函数的签名相同(请记住,它的重要性,稍后我们将看到)
    struct foo
    {
    static void f();
    {

    int main()
    {
    foo::f(); //Call to foo::f
    }
  • 函子:函子只是一个类,对象被设计为在其功能所在的地方工作。那实现了重载()运算符:
    struct f
    {
    void operator()() const
    {}
    };

    int main()
    {
    f myf;

    myf(); //Call to foo
    }

    标准库定义了模板std::function,它是一种类型为擦除的函子,旨在容纳任何类型的可调用实体:
    #include <functional>

    void f() {}

    int main()
    {
    std::function<void()> f_wrapper;

    f_wrapper(); //Call to f_wrapper, which is an indirect call to f
    }
  • lambda表达式: lambda表达式只是就地定义的匿名函子:
    int main()
    {
    std::function<void()> lambda = [](){ std::cout << "hello!"; };
    }

    Hello!

  • 指向函数的指针: C允许用户通过函数指针存储函数,就像它允许存储指向数据的指针一样。 C++具有相同的功能,也扩展了成员功能:
    void f() {}
    void g( void(*function)() )
    {
    function(); //Call to the function referenced by the pointer passed as parameter
    }

    int main()
    {
    g(f); //Call to g passing f as parameter. Its an indirect call to f. Note that the & is not needed
    }

    如上所述,静态成员函数与全局函数具有相同的签名,因此语法与上面的示例完全相同。
    但是对于成员函数来说是不一样的:成员函数链接到对象,因此在对象中调用它。成员函数指针的语法如下:
    struct foo
    {
    voif f();
    };

    typedef void(foo::* pointer_to_f_type)();

    int main()
    {
    pointer_to_f_pointer ptr = &foo::f; //Note that the & is needed, just like in variable pointers
    foo myfoo;

    (myfoo.*ptr)(); //Call to the foo member function pointed by ptr (foo::f) using myfoo as object
    }

    特定签名的成员函数指针与指向相同签名的全局/静态函数的指针无关
    签名,并且不能与成员指针/从成员指针转换为非成员指针,反之亦然


    因为函数指针和成员函数指针是完全分开的东西,所以我们无法处理任何类型的函数
    直接以同质方式。
    例如,我们不能创建一个既包含函数指针又包含成员函数指针的数组。
    但是,标准库提供了函数模板std::bind,该模板允许我们将函数绑定(bind)到某些(或全部)调用参数。
    也就是说,std::bind()返回的对象表示对可调用实体的部分(或完整)调用。
    例如:
     void f( int , int , int ) {}

    int main()
    {
    std::function<void(int,int,int)> f_wrapper = f;

    f(1,2,3); //Ok
    f_wrapper(1,2,3); //Ok

    std::function<void()> f_call = std::bind( f , 1 , 2 , 3 ); //f_call represents a partial call (Complete in this case) fo f
    f_call(); //Execute the call

    std::function<void(int)> partial_f_call = std::bind( f , std::placeholders::_1 , 2 , 3 );
    partial_f_call( 1 ); //Same execution as above
    }

    如您所见,std::bind()允许我们将某些参数绑定(bind)到函数,从而创建一个可调用的实体,
    表示对该函数的调用。因此它可以用于将对象绑定(bind)到成员函数,从而形成可调用的实体
    具有与其他任何类型的可调用实体初始化的std::function实例完全相同的形式。
    那是
    我们可以使用std::function以相同的方式存储成员和非成员函数,并以相同的方式使用**:
     void f();

    struct foo
    {
    void f();
    };

    int main()
    {
    std::vector<std::function<void()>> functions;
    foo myfoo;

    functions.push_back( f );
    functions.push_back( std::bind( &foo::f , myfoo ) );
    functions.push_back( [](){} );
    ...

    for( const auto& function : functions )
    function();
    }

  • 如您所见,可调用实体有多种形式。重要的一点是,有人可以使用C++模板并依靠鸭子的类型来使用可调用对象
    实体作为参数传递:
     template<typename F>
    void call_function( const F& function )
    {
    function(); //function should be any kind of thing which could be called, that is, a callable entity
    }

    正是std::thread构造函数执行。它只需要任何种类的可调用实体,一组调用参数,启动一个新线程,
    然后在该新线程(通过 join()detach())上调用可调用实体。其实现可能类似于:
    template<typename F , typename... ARGS>
    thread::thread( F&& function , ARGS&&... args )
    {
    _thread = create_thread();

    _function = std::bind( std::forward<F>( function ) , std::forward<ARGS>( args )... );
    }


    void thread::detach()
    {
    detach_thread( _thread );
    _function();
    }

    void thread::join()
    {
    join_thread( _thread );
    _function();
    }

    当然,这不是可行的实现,只是一个概述:p

    因此,现在您可以了解为什么您的方法行不通了,以及可以采取什么措施来解决该问题。具体来说, 使用std::bind()创建可调用实体
    如果要在线程
    上使用成员函数。

    关于c++ - 未解析的外部符号(构造函数),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22414526/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com