面向物件程式設計風格與基於物件程式設計風格
阿新 • • 發佈:2018-11-27
使用面向物件風格對執行緒類封裝
#ifndef _THREAD_H_
#define _THREAD_H_
#include <pthread.h>
class Thread
{
public:
Thread();
virtual ~Thread();
void Start();
void Join();
void SetAutoDelete(bool autoDelete);
private:
static void* ThreadRoutine(void* arg);
virtual void Run() = 0 ; // Run是普通的成員函式,隱含的第一個引數是 Thread*(this)
pthread_t threadId_;
bool autoDelete_;
};
#endif
#include "Thread.h"
#include <iostream>
using namespace std;
Thread::Thread() : autoDelete_(false)
{
cout << "Thread ..." << endl;
}
Thread::~Thread()
{
cout << "~Thread ..." << endl;
}
void Thread::Start()
{
pthread_create(&threadId_, NULL, ThreadRoutine, this);
}
void Thread::Join()
{
pthread_join(threadId_, NULL);
}
void* Thread::ThreadRoutine(void* arg) // 靜態成員函式不能呼叫非靜態的成員函式
{
Thread* thread = static_cast<Thread*>(arg);
thread->Run();
if (thread->autoDelete_) // 靜態成員函式不能呼叫非靜態的成員變數,使用指標訪問
delete thread;
return NULL;
}
void Thread::SetAutoDelete(bool autoDelete)
{
autoDelete_ = autoDelete;
}
#include "Thread.h"
#include <unistd.h>
#include <iostream>
using namespace std;
class TestThread : public Thread
{
public:
TestThread(int count) : count_(count)
{
cout << "TestThread ..." << endl;
}
~TestThread()
{
cout << "~TestThread ..." << endl;
}
private:
void Run()
{
while (count_--)
{
cout << "this is a test ..." << endl;
sleep(1);
}
}
int count_;
};
int main()
{
/*
TestThread t(5); // 執行緒物件與執行緒的生命週期不同,執行緒物件知道程式結束才銷燬,如何讓它線上程結束後自動銷燬?
t.Start();
t.Join();
*/
TestThread* t2 = new TestThread(5);
t2->SetAutoDelete(true);
t2->Start();
t2->Join();
for (; ;)
pause();
return 0;
}
基於物件程式設計風格對執行緒類的封裝
#ifndef _THREAD_H_
#define _THREAD_H_
#include <pthread.h>
#include <functional>
class Thread
{
public:
typedef std::function<void ()> ThreadFunc;
explicit Thread(const ThreadFunc& func);
//virtual ~Thread();
void Start();
void Join();
void SetAutoDelete(bool autoDelete);
private:
static void* ThreadRoutine(void* arg); // 類普通成員函式是thiscall呼叫約定,而ptread_create需要一個普通函式,
// 因此加上static後變為普通函式,再將this指標作為引數傳遞
void Run(); // Run是普通的成員函式,隱含的第一個引數是 Thread*(this)
ThreadFunc func_;
pthread_t threadId_;
bool autoDelete_;
};
#endif
#include "Thread.h"
#include <iostream>
using namespace std;
Thread::Thread(const ThreadFunc& func) : func_(func), autoDelete_(false)
{
cout << "Thread ..." << endl;
}
//Thread::~Thread()
//{
// cout << "~Thread ..." << endl;
//}
void Thread::Start()
{
pthread_create(&threadId_, NULL, ThreadRoutine, this);
}
void Thread::Join()
{
pthread_join(threadId_, NULL);
}
void* Thread::ThreadRoutine(void* arg) // 靜態成員函式不能呼叫非靜態的成員函式
{
Thread* thread = static_cast<Thread*>(arg);
thread->Run();
if (thread->autoDelete_) // 靜態成員函式不能呼叫非靜態的成員變數,使用指標訪問
delete thread;
return NULL;
}
void Thread::SetAutoDelete(bool autoDelete)
{
autoDelete_ = autoDelete;
}
void Thread::Run()
{
func_();
}
#include "Thread.h"
#include <unistd.h>
#include <iostream>
using namespace std;
class Foo
{
public:
Foo(int count) : count_(count)
{
cout << "Foo ..." << endl;
}
void MemberFun()
{
while (count_--)
{
cout << "this is a test ..." << endl;
sleep(1);
}
}
int count_;
};
void ThreadFunc()
{
cout << "ThreadFunc ..." << endl;
}
void ThreadFunc2(int count)
{
while (count--)
{
cout << "ThreadFunc2 ..." << endl;
sleep(1);
}
}
int main()
{
Thread t1(ThreadFunc);
Thread t2(std::bind(ThreadFunc2, 3)); // 普通函式引數取地址可省略
Foo foo(3);
Thread t3(std::bind(&Foo::MemberFun, &foo)); // 成員函式取地址不可省略,&foo為省略引數,相當於this指標
t1.Start();
t2.Start();
t3.Start();
t1.Join();
t2.Join();
t3.Join();
return 0;
}
總結:
面向物件的程式設計會暴露抽象類,利用虛擬函式的多型性回撥相應介面
基於物件的程式設計只使用具體類,不暴露抽象類,應用類並不是繼承抽象類,而是包含一個具體類的物件,然後將具體類的實現繫結為相應的回撥