在 C++ 中,如何确定 class 是否是继承链中的最后一个 class/child?即在底座的另一端class
In C++, how do I determine if a class is the last class/child in an inheritance chain? ie on the opposite end of the base class
我无法简洁地表述这个问题,但基本上 class 中有一个函数可能是继承链中的最后一个 class,也可能不是。在此函数内部,如果 class 级函数是继承链中的最后一个函数,将调用第二个函数。展示我在说什么比解释它容易得多,所以:
假设我有 class Z。
Z 派生自 Y,Y 派生自 X,X 派生自 W。
所有 classes 都有一个名为 Execute() 的虚函数。
Z.Execute() 要求 Y.Execute() 完成,这要求 X.Execute() 完成,这要求 W.Execute() 完成。
因此,Z 的 Execute() 函数如下所示:
void Z::Execute(void)
{
Y::Execute();
// do Z's stuff!
return;
}
同样,Y 的 Execute() 函数如下所示:
void Y::Execute(void)
{
X::Execute();
// do Y's stuff!
return;
}
依此类推继承链。
但是 Y、X 和 W 都不是抽象的,因此每个都可以实例化,并且可能是也可能不是继承链中的最后一个 class。
这是我需要知道的。最后一个Execute()需要调用DoThisAtEndOfExecute()。 DoThisAtEndOfExecute() 需要在 classes 内部调用,即。不会是 public.
所以它不能在X的Execute()中,因为如果class是一个Y,它会被调用得太早。它不能在 Y 的 Execute() 中,因为 class 可能是一个 Z。它不能在 Z 的 Execute() 中,因为如果 class 是一个 Y、X 或 W,该函数将永远不会被调用。
那么class有什么方法可以判断它是否是从FROM继承的呢?基本上,相当于:
if (!IAmTheParentOfSomething)
DoThisAtEndOfExecute();
这是怎么做到的?我承认更简单的方法是让包含 class 的函数执行:
X.Execute();
X.DoThisAtEndOfExecute();
但这并不是此代码的真正选择。
一种可能的解决方案是向 Execute 添加一个默认参数,并在后续调用中将该参数更改为其他值。
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
传递给方法来防止执行上述终止代码(如果您愿意)。
我觉得把Execute拆分成非虚拟部分和虚拟部分就可以达到你想要的效果。前者将 运行 后者,然后调用 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()
并调用基地。这样,在 ExecuteImpl() 的最派生版本完成后 DoThisAtEndOfExecute()
运行s,不知道实际的 class。
移动//做的东西怎么样!进入一个单独的函数?
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();
};
};
我无法简洁地表述这个问题,但基本上 class 中有一个函数可能是继承链中的最后一个 class,也可能不是。在此函数内部,如果 class 级函数是继承链中的最后一个函数,将调用第二个函数。展示我在说什么比解释它容易得多,所以:
假设我有 class Z。
Z 派生自 Y,Y 派生自 X,X 派生自 W。
所有 classes 都有一个名为 Execute() 的虚函数。
Z.Execute() 要求 Y.Execute() 完成,这要求 X.Execute() 完成,这要求 W.Execute() 完成。
因此,Z 的 Execute() 函数如下所示:
void Z::Execute(void)
{
Y::Execute();
// do Z's stuff!
return;
}
同样,Y 的 Execute() 函数如下所示:
void Y::Execute(void)
{
X::Execute();
// do Y's stuff!
return;
}
依此类推继承链。
但是 Y、X 和 W 都不是抽象的,因此每个都可以实例化,并且可能是也可能不是继承链中的最后一个 class。
这是我需要知道的。最后一个Execute()需要调用DoThisAtEndOfExecute()。 DoThisAtEndOfExecute() 需要在 classes 内部调用,即。不会是 public.
所以它不能在X的Execute()中,因为如果class是一个Y,它会被调用得太早。它不能在 Y 的 Execute() 中,因为 class 可能是一个 Z。它不能在 Z 的 Execute() 中,因为如果 class 是一个 Y、X 或 W,该函数将永远不会被调用。
那么class有什么方法可以判断它是否是从FROM继承的呢?基本上,相当于:
if (!IAmTheParentOfSomething)
DoThisAtEndOfExecute();
这是怎么做到的?我承认更简单的方法是让包含 class 的函数执行:
X.Execute();
X.DoThisAtEndOfExecute();
但这并不是此代码的真正选择。
一种可能的解决方案是向 Execute 添加一个默认参数,并在后续调用中将该参数更改为其他值。
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
传递给方法来防止执行上述终止代码(如果您愿意)。
我觉得把Execute拆分成非虚拟部分和虚拟部分就可以达到你想要的效果。前者将 运行 后者,然后调用 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()
并调用基地。这样,在 ExecuteImpl() 的最派生版本完成后 DoThisAtEndOfExecute()
运行s,不知道实际的 class。
移动//做的东西怎么样!进入一个单独的函数?
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();
};
};