C++ 类继承的深入理解(未完待续)

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

说起继承,就是对现有的类的方法和字段进行重复的使用

(1)公有继承父类的方法,继承完父类所有的属性,都继承到了子类,这些字段都是子类的了,

不存在是父类的,还是子类的字段,都是子类的。只是子类能否用自己继承的方法进行访问而已。 

对于父类的私有成员,虽然子类可以继承这个方法,但是要依靠父类的方法,进行访问自己继承下来的字段。

上面的这些总结有点饶口,重新梳理下,简单的解释如下:在公有继承的方式下

在父类的访问属性 在子类中的访问属性
public(公用) public
private(私有) private
protected(保护) 不可访问

这里有一点一定要明确,子类继承了父类的私有成员,包括,私有的数据成员和成员函数,在子类的访问属性是不可访问是

指在子类中的新增成员函数,或者是重写的成员函数里,不能够进行访问,从父类继承过来的成员函数,还是可以访问的。

这个一定要分清,从父类继承过的函数,是代码的公用。                                                                           

class ICommandRunnable :virtual public IRunable
{
public:
    ICommandRunnable();
    virtual ~ICommandRunnable();
public:
    virtual void PushCommand(BaseCommand *cmd, bool front = false);
protected:
    virtual void ClearCommand();
    virtual BaseCommand *PopCommand();
private:
    std::deque<BaseCommand*> _cmds;
    CLock _cmds_lock;

};

像上面这个类,是一个父类,但是它的_cmds字段,子类继承以后是访问不了的,需要借助继承到自身子类的父类方法进行访问。

class TestICommand :public ICommandRunnable
{
public:
TestICommand();
~TestICommand();
//线程执行函数
//virtual void  PushCommand(BaseCommand *cmd, bool front = false);
void run();
private:
//线程启动锁
bool m_bIsRunning;
CLock m_lkRunLock;
SegEvent m_evtWait;

};

void TestICommand::run()
{
while (m_bIsRunning)
{

BaseCommand* pCmd = NULL;              
PushCommand(pCmd);                                 //这里只是代码的构成,并不是真实的写法,只是为了解释而进行的代码书写
if ((pCmd = (BaseCommand*)PopCommand()) == NULL)

{
m_evtWait.wait(3000);
continue;
}
}

}

像上面的两个方法,一个是父类的公有成员函数 PushCommand,一个是父类的受保护成员函数PopCommand

(受保护的成员函数在父类里相当于私有成员,只是继承到子类的时候,子类内部可以访问,该成员,在类外是不能访问的,这里在强调下什么是类内,就是在定义类的时候,类的成员函数可以进行访问,而外部直接定义一个类对象,然后直接访问对象的成员属性是访问不了的。)

子类继承了这个方法,然后是可以直接使用的,来访问 继承到自身的,父类的私有成员,_cmds,如果你把父类的两个方法改成private那就不行了,子类虽然继承过来这个方法,但是不能访问,像上面那样调用就会报错了。

而另外还有一种方式,就是你想继承父类的方法,你感觉你除了要做父类的事以外,你还想要干点其它的事,也就是说父类写的方法,pushcommand不能够满足你的需求 了,那就可以对父类的方法进行重写。

如下所示:

class TestICommand :public ICommandRunnable
{
public:
TestICommand();
~TestICommand();
//线程执行函数
virtual void  PushCommand(BaseCommand *cmd, bool front = false);
void run();
private:
//线程启动锁
bool m_bIsRunning;
CLock m_lkRunLock;
SegEvent m_evtWait;

};

void  TestICommand::PushCommand(BaseCommand *cmd, bool front = false)
{
//_cmds.push_front(cmd);

ICommandRunnable::PushCommand(cmd);

        m_evtWait.set();

}

我在pushcommand后想让线程跑起来,就得添加一个m_evtWait.set();而原来的父类的函数就满足不了需求了,

就可以采用两种方式来处理这个问题

(1)我就要对这个方法进行重写,也就是多态,然而我会先不调用父类父类的方法,我想直接按照红色部分操作,这是不可以的,因为这个字段在父类那里是私有的,子类自己写的方法是不能进行访问的,所以要用父类的方法进行访问,所以应该写成第二种绿色的形式,进行访问,然后后面再加上额外的操作。

(2)不用对父类的方法进行重写,原来继承下来的方法继续使用,新定于一个方法,Start.

如下代码所示:

class  Threadimpl
{
public:
Threadimpl();
virtual ~Threadimpl();
void  startimpl(IRunable* prunable);
void  joinImpl();
bool  joinImpl(int  milliseconds);
bool  isRunningImpl() const;
static void sleepImpl(int milliseconds);
#if defined(_USRDLL)
typedef DWORD(WINAPI *Entry)(LPVOID);
#else
typedef unsigned(__stdcall *Entry)(void*);
#endif
protected:
void threadCleanup();
//#if defined(_USRDLL)
static DWORD WINAPI runnableEntry(LPVOID pThread);
//#else
// static unsigned  runnableEntry(void* pThread);
//#endif


private:
IRunable* _pRunnableTarget;
int _stackSize;
int _nParam;
HANDLE _thread;
};
inline void Threadimpl::sleepImpl(int milliseconds)
{
Sleep(DWORD(milliseconds));
}


class  Thread : public Threadimpl
{
public:
Thread();
virtual ~Thread();
void  start(IRunable* prunable);//下面的所有函数都是直接调用父类的函数
void join();
bool join(int milliseconds);
bool isRunning() const;
static void sleep(int milliseconds);
};

class TestICommand :public ICommandRunnable,public Thread
{
public:
TestICommand();
~TestICommand();
//线程执行函数
bool Start();
bool Stop();
void run();
private:
//线程启动锁
bool m_bIsRunning;
CLock m_lkRunLock;
SegEvent m_evtWait;

 

};

bool TestICommand::Start()
{
if (!m_bIsRunning)
{
m_evtWait.reset();
m_bIsRunning = true;
start(this);
}
return true;
}


bool TestICommand::Stop()
{
if (m_bIsRunning)
{
m_bIsRunning = false;
m_evtWait.set();
join();
}
return true;
}

函数里调用继承的函数,然后再添加自己想要的处理,这样也可以满足需求。这个是针对TestICommand 继承Thread来举例说明的

猜你喜欢

转载自blog.csdn.net/zhanghuaichao/article/details/79416574