面向对象编程风格与基于对象编程风格

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/TS1130/article/details/80577126

使用面向对象风格对线程类封装

#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;
}

总结:
面向对象的编程会暴露抽象类,利用虚函数的多态性回调相应接口
基于对象的编程只使用具体类,不暴露抽象类,应用类并不是继承抽象类,而是包含一个具体类的对象,然后将具体类的实现绑定为相应的回调

阅读更多

没有更多推荐了,返回首页