C++ 未解析的外部符号(构造函数)
在building,我得到以下错误: main.obj:错误LNK2019:未解析的外部符号“public:u cdecl Worker::Worker(void)”(??0 Worker@@QEAA@XZ)在函数“main”中 main.obj:错误LNK2019:未解析的外部符号“public:virtual\uu cdecl Worker::~Worker(void)”(??1Worker)@@UEAA@XZ)在函数“main”中 我找不到问题。(我也看了看) main.cppC++ 未解析的外部符号(构造函数),c++,lnk2019,C++,Lnk2019,在building,我得到以下错误: main.obj:错误LNK2019:未解析的外部符号“public:u cdecl Worker::Worker(void)”(??0 Worker@@QEAA@XZ)在函数“main”中 main.obj:错误LNK2019:未解析的外部符号“public:virtual\uu cdecl Worker::~Worker(void)”(??1Worker)@@UEAA@XZ)在函数“main”中 我找不到问题。(我也看了看) main.cpp #incl
#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;
}
#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();
}
<强>删除项目。PRO.U.S.解决了(主要)问题,现在错误再次显示>/P>> P>代码中有很多错误,因为我建议您在此之前应该学习更多C++基础知识。 正如我在评论中指出的错误,让我只回答您关于成员函数的问题:
C++将函数视为一等公民,而不是Java(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 f { void operator()() const {} }; int main() { f myf; myf(); //Call to foo }
,这是一个类型擦除的functor,用于保存任何类型的可调用实体: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 }
但对于成员函数则不同:成员函数链接到对象,因此在对象中调用它。成员函数指针的语法如下所示:
特定签名的成员函数指针与指向相同签名的全局/静态函数的指针无关 签名,并且不能从/到成员指针转换为非成员指针,反之亦然 因为函数指针和成员函数指针是完全分离的东西,我们不能处理任何类型的函数 例如,我们不能创建一个同时包含函数指针和成员函数指针的数组。 但是,标准库提供了函数模板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
返回的对象表示对可调用实体的部分(或完整)调用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 }
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
}
当然,这不是一个有效的实现,只是一个概述:p
因此,现在您可以理解为什么您的方法不起作用,以及您可以做些什么来解决这个问题。具体来说,使用std::bind()
创建一个可调用的实体
如果要在线程上使用成员函数是否链接文件?您必须提供所有用于链接的对象文件。您可能没有包含worker.o对象文件。作为IDE,我使用QT Creator和MSVC 2012 64位作为编译器。我将在上面发布我的项目文件。C++类的构造函数和解构主义的调用约定为:很难猜到你是怎么做到的。删除project.pro.user文件后,我得到了编译错误@MUN33626我用这个来学习C++。我从java切换,所以我在C++中没有PRO。在C++中,你必须知道java中的所有错误,编译器有更好的错误检测。顺便问一下,如果我想让线程调用Worker::work()方法,最好的方法是什么?谢谢你的工作!这个话题对我来说还是有点神秘。在编译器给了我实际的错误后,我解决了我的问题。我的解决方案仍然是Javastyle,而不是C++风格,但它现在可以工作了。我会用你的建议重构我的代码,谢谢。@ NICCOMATIK我知道在这个帖子里有太多的信息,用于C++ NeBBIE。我只是想告诉你你犯错误的原因。我建议你读一本好的C++书籍(检查这个网站的C++常见问题),然后搜索关于语言最重要的主题的好的问题/答案。
int main()
{
std::function<void()> lambda = [](){ std::cout << "hello!"; };
}
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
}
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
}
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();
}
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
}
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();
}