PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > comp.lang.cplus > nested classes and derivation
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
nested classes and derivation

Réponse
 
LinkBack Outils de la discussion
Vieux 08/02/2008, 21h06   #1
Christopher
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut nested classes and derivation

This is going to be hard to explain. But I am looking for rules on
deriving nested classes in a scenario like the following:

class TaskLauncher
{
// launches tasks which are child threads

typedef std::vector<BaseTask *> Tasks
Tasks m_tasks;

// desire to be able to dynamic cast BaseTask pointer to a concrete
task type
// and be able to retreive its stats when stats can be differant
types

};


class BaseTask
{
public:
...

private:
class TaskStats
{
public:
virtual const std::string GetStats() const;

...

private:
m_somestat;
}m_stats;
};


class Task1 : public BaseTask
{
public:
...

private:
class Task1Stats : public TaskStats
{
public:
virtual const std::string GetStats() const;

private:
m_somestat;
m_otherstat;
}m_stats;
};


I don't really nest classes very often, but I figured it would be
convienant when users of the class want a particualr kind of stats
that they can qualify it with the task type. i.e Task1::m_stats or
BaseTask::m_stats and get the proper type of stats.

Do the names of member variables get overidden properly? i.e does
Task1::m_stats contain a m_otherstats member?

Is there a problem with Task1 being derived from BaseTask while its
nested Task1Stats is derived from TaskStats?

Did I get the syntax correct in my scenario example?
  Réponse avec citation
Vieux 08/02/2008, 21h57   #2
Victor Bazarov
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: nested classes and derivation

Christopher wrote:
> This is going to be hard to explain. But I am looking for rules on
> deriving nested classes in a scenario like the following:
>
> class TaskLauncher
> {
> // launches tasks which are child threads
>
> typedef std::vector<BaseTask *> Tasks
> Tasks m_tasks;
>
> // desire to be able to dynamic cast BaseTask pointer to a concrete
> task type
> // and be able to retreive its stats when stats can be differant
> types
>
> };
>
>
> class BaseTask
> {
> public:
> ...
>
> private:
> class TaskStats
> {
> public:
> virtual const std::string GetStats() const;
>
> ...
>
> private:
> m_somestat;
> }m_stats;
> };
>
>
> class Task1 : public BaseTask
> {
> public:
> ...
>
> private:
> class Task1Stats : public TaskStats
> {
> public:
> virtual const std::string GetStats() const;
>
> private:
> m_somestat;
> m_otherstat;
> }m_stats;
> };
>
>
> I don't really nest classes very often, but I figured it would be
> convienant when users of the class want a particualr kind of stats
> that they can qualify it with the task type. i.e Task1::m_stats or
> BaseTask::m_stats and get the proper type of stats.
>
> Do the names of member variables get overidden properly? i.e does
> Task1::m_stats contain a m_otherstats member?


Well, yes, but you do realise that an object of type 'Task1'
will have _two_ members 'm_stats', don't you? The one stored
in the base class subobject is going to be used when the base
class function is called that refers to it, and the derived
class 'm_stats' are going to be used by the derived class'
member funciton. Confusion up to wazoo.

> Is there a problem with Task1 being derived from BaseTask while its
> nested Task1Stats is derived from TaskStats?
>
> Did I get the syntax correct in my scenario example?


You probably did. I am not sure it's the right design, though.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


  Réponse avec citation
Vieux 09/02/2008, 19h21   #3
Grizlyk
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: nested classes and derivation

Christopher wrote:
>
> This is going to be hard to explain. But I am looking for rules on
> deriving nested classes in a scenario like the following:
>
> class TaskLauncher
> {
> // launches tasks which are child threads
>
> typedef std::vector<BaseTask *> Tasks;
> Tasks m_tasks;
>
> // desire to be able to dynamic cast BaseTask pointer
> // to a concrete task type and be able to retreive
> // its stats when stats can be differant types
>
> };
>
> class BaseTask
> {
> public:
> ...
>
> private:
> class TaskStats
> {
> public:
> virtual const std::string GetStats() const;
>
> ...
>
> private:
> m_somestat;
> }m_stats;
>
> };
>
> class Task1 : public BaseTask
> {
> public:
> ...
>
> private:
> class Task1Stats : public TaskStats
> {
> public:
> virtual const std::string GetStats() const;
>
> private:
> m_somestat;
> m_otherstat;
> }m_stats;
>
> };
>
> I don't really nest classes very often, but I figured it would be
> convienant when users of the class want a particualr kind of stats
> that they can qualify it with the task type. i.e Task1::m_stats or
> BaseTask::m_stats and get the proper type of stats.
>
> Do the names of member variables get overidden properly? i.e does
> Task1::m_stats contain a m_otherstats member?


Certainly, but not sure you have properly selected "private" access
modifier for Task1::m_stats and BaseTask::m_stats, to inherite
interface (access) you should use at least "protected", to use
external access you should use "public".

Of course, you need to declare for BaseTask at least one virtual
method (destructor, for example) to do dinamic_cast<>

> Is there a problem with Task1 being derived
> from BaseTask while its nested Task1Stats
> is derived from TaskStats?


The problem is the fact that you are inheriting implementation. There
is often hard to maintain, share and upgrade the kind of inheritance
for a lot of classes.

For Task1Stats - do you really want two copies of m_somestat for
Task1Stats and Task1Stats with exact behaviour of TaskStats?

For Task1 - do you really want Task1 with exact behaviour of BaseTask?

Otherwise you can make abstract TaskStats and BaseTask classes and
inherite from them:

namespace Nabs{

//
class TaskStats
{
public:
virtual
const std::string
GetStats() const
=0;

virtual ~TaskStats(){}
};

//
class BaseTask
{
public:
virtual ~BaseTask(){}
};

//namespace Nabs
}

//
class BaseTask: public Nabs::BaseTask
{
protected:
class Implementation {...};

public:
class TaskStats: public Nabs::TaskStats
{
public:
const std::string
GetStats() const;

private:
Implementation
m_somestat;

}m_stats;

};

//
class Task1: public Nabs::BaseTask
{
protected:
class Implementation {...};

public:
class TaskStats: public Nabs::TaskStats
{
public:
const std::string
GetStats() const;

private:
Implementation
m_otherstat;

}m_stats;
};

If dynamic_cast<> will be used only to select proper m_stats, then
"virtual" access for m_stats is better - less expensive at runtime
than dynamic_cast<>. In the case you can make abstract BaseTask and
TaskStats

//prev TaskStats
namespace Nabs{
class TaskStats;}

//new BaseTask
namespace Nabs{
class BaseTask
{
public:
virtual
Nabs::TaskStats&
task_stat()
=0;

virtual
const Nabs::TaskStats&
task_stat()const
=0;

virtual ~BaseTask(){}
};}

namespace Ncct
{

//
template< class pImplementation >
class AbstractTask: public Nabs::BaseTask
{
protected:
class TaskStats: public Nabs::TaskStats
{
public:
const std::string
GetStats() const;

private:
pImplementation
m_somestat;
};

public:
//AbstractTask::TaskStats&
TaskStats&
task_stat()
{ return m_stats; }

//const AbstractTask::TaskStats&
const TaskStats&
task_stat()const
{ return m_stats; }

private:
//AbstractTask::TaskStats
TaskStats
m_stats;
};

// ***
//class BaseTask

//declare & define
class BaseImplementation {};

//define
template<>
const std::string
AbstractTask<BaseImplementation>::
TaskStats::
GetStats() const;

//or
//template<>class
//AbstractTask<BaseImplementation>::
// TaskStats;

//declare
typedef
AbstractTask<BaseImplementation>
BaseTask;


// ***
//class Task1

//declare & define
class Task1Implementation {};

//define
template<>
const std::string
AbstractTask<Task1Implementation>::
TaskStats::
GetStats() const;

//or
//template<>class
//AbstractTask<Task1Implementation>::
// TaskStats;

//declare
typedef
AbstractTask<Task1Implementation>
Task1;

//namespace Ncct
}

Ncct::BaseTask task;
Ncct::Task1 task1;
Nabs::BaseTask *ar[]={&task,&task1};

void foo()
{
ar[0]->task_stat().GetStats();
ar[1]->task_stat().GetStats();
}

Maksim A. Polyanin
http://grizlyk1.narod.ru/cpp_new
  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 05h26.


Édité par : vBulletin® version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières ©2000-2008
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,14818 seconds with 11 queries