C++ 在C++;,如何确定类是否是继承链中的最后一个类/子类?即在基类的另一端
我在简洁地表述这个问题时遇到了一些问题,但基本上,类中有一个函数可能是继承链中的最后一个类,也可能不是。在该函数中,如果类级函数是继承链中的最后一个,则将调用第二个函数。展示我所说的比解释要容易得多,因此: 假设我有Z班 Z从Y派生,Y从X派生,X从W派生 所有类都有一个名为Execute()的虚拟函数 Z.Execute()要求Y.Execute()完成,这要求X.Execute()完成,这要求W.Execute()完成 因此,Z的Execute()函数如下所示:C++ 在C++;,如何确定类是否是继承链中的最后一个类/子类?即在基类的另一端,c++,class,inheritance,children,C++,Class,Inheritance,Children,我在简洁地表述这个问题时遇到了一些问题,但基本上,类中有一个函数可能是继承链中的最后一个类,也可能不是。在该函数中,如果类级函数是继承链中的最后一个,则将调用第二个函数。展示我所说的比解释要容易得多,因此: 假设我有Z班 Z从Y派生,Y从X派生,X从W派生 所有类都有一个名为Execute()的虚拟函数 Z.Execute()要求Y.Execute()完成,这要求X.Execute()完成,这要求W.Execute()完成 因此,Z的Execute()函数如下所示: void Z::Execut
void Z::Execute(void)
{
Y::Execute();
// do Z's stuff!
return;
}
void Y::Execute(void)
{
X::Execute();
// do Y's stuff!
return;
}
类似地,Y的Execute()函数如下所示:
void Z::Execute(void)
{
Y::Execute();
// do Z's stuff!
return;
}
void Y::Execute(void)
{
X::Execute();
// do Y's stuff!
return;
}
等等,沿着继承链往下走
但是Y、X和W都是抽象的,因此每个都可以实例化,并且可能是也可能不是继承链中的最后一个类
这是我需要知道的。最后一个Execute()需要调用DoThisAtEndOfExecute()。DoThisAtEndOfExecute()需要在类内部调用,即它不是公共的
所以它不能在X的Execute()中,因为如果类是Y,那么调用它就太早了。它不能在Y的Execute()中,因为该类可能是Z。它不能在Z的Execute()中,因为如果该类是Y、X或W,则永远不会调用该函数
那么类有没有办法判断它是否是从继承来的呢?基本上相当于:
if (!IAmTheParentOfSomething)
DoThisAtEndOfExecute();
这是怎么做到的?我承认,对于包含类的函数来说,更简单的方法是:
X.Execute();
X.DoThisAtEndOfExecute();
但这并不是这段代码的真正选项。一种可能的解决方案是添加一个要执行的默认参数,并在后续调用中将该参数更改为其他值
class X{
void Execute(bool isFinal = true);
};
//and so on.
void Z::Execute(bool isFinal)
{
Y::Execute(false);
// do Z's stuff!
if(isFinal){
// You're up!
}
return;
}
void Y::Execute(bool isFinal)
{
X::Execute(false);
// do Y's stuff!
if(isFinal){
// Y is the last class in this chain.
}
return;
}
这样,每当代码调用对象的
Execute
方法(不带参数)时,就会告诉该方法有一些外部代码正在执行它。这还允许您通过将false
传递给该方法来防止所述终止代码被执行(如果您选择的话)。我认为如果您将执行分为非虚拟部分和虚拟部分,则可以实现您想要的。前者将运行后者,然后调用DoThisAtEndOfExecute
。像这样:
class X
{
public:
void Execute()
{
ExecuteImpl(); //That one's virtual, the derived classes override it
DoThisAtEndOfExecute();
}
protected:
virtual void ExecuteImpl()
{
//Whatever was in the legacy Execute
}
}
Y和Z覆盖
ExecuteImpl()
并调用基。这样,DoThisAtEndOfExecute()
在最派生的ExecuteImpl()版本完成后运行,而不知道实际的类 移动//do…(做…)的东西怎么样!变成一个独立的函数
class W
{
protected:
void Stuff() { /*...*/ };
void Finalize() { /*...*/ };
public:
virtual ~W() {}
virtual void Execute() { /*...*/ };
};
class X : public W
{
protected:
void Stuff() {
// X Stuff
W::Stuff();
};
public:
virtual ~X() {}
virtual void Execute() {
X::Stuff();
W::Finalize();
};
};
class Y : public X
{
void Stuff() {
// Y Stuff
X::Stuff();
};
public:
virtual ~Y() {}
virtual void Execute() {
Y::Stuff();
W::Finalize();
};
};
可以保护成员函数。这样,它只对声明类及其派生类可用。就像你想的那样,这是公共和私人之间的中间。我早就想到了。我希望有一些实际的内置功能。不幸的是,没有办法知道一个类本身是否离基类最远(至少我不知道怎么说)。但是,始终有一种方法可以让对象知道它是否被外部调用(如您所知)。我想知道你是否在这里遇到了X-Y问题?我想你和塞瓦·阿列克谢耶夫的想法是相似的。这里的区别是
Execute()
而不是Stuff()
是虚拟的,你能解释一下你为什么走这条路吗?在所有不同的Execute()
实现之后,基本上避免了虚拟查找,但在其他方面也做了相同的操作……我只想说明分离,以实现所需的行为。Imho非虚拟接口更可取。我会将Execute()
公开,并对ExecuteImpl()
进行保护,以允许堆叠。AKA“Template Method”。AKA。