好吧所以我无法在任何地方找到答案,这是我的第一篇文章,所以请善待。 基本上,如果某个子类在某些条件下调用父函数,我需要抛出异常,但另一个子类应始终能够执行该函数。
- 如果您想知道,它是一个带有储蓄和支票子类的帐户类的提款功能。储蓄具有最小余额(如果撤销导致其低于最小值,则抛出异常)但是检查没有最小值
class parent {
public:
int b;
void A(){
//1. Throws exception if b < # ONLY when child1 calls
//2. Always executes code if child2 calls regardless of condition
}
}
class child1 : public parent {
}
class child2 : public parent {
}
int main(){
child1 one;
child2 two;
one.A(); //This needs to throw exception under certain conditions
two.A(); //This will always execute
}
任何人都有任何提示如何确定哪个子类正在调用该函数?
答案 0 :(得分:2)
没有循环依赖关系,没有简单的方法可以做到这一点。可能最简单的方法是在每个类中重载函数:
class Child1 : public Parent
{
void A(int v)
{
if (this->b > v)
{
throw 1;
}
else
{
Parent::A(v);
}
return;
}
}
您还可以在基类中使函数为pure virtual,以强制所有子项使用自己的副本覆盖该函数。
class Parent
{
virtual void A() =0;
}
class Child1 : public Parent
{
void A(int v)
{
if (this->b > v)
{
throw 1;
}
else
{
<<do something>>
}
return;
}
}
或者,您可以使用Functors,但这些可能变得非常复杂并且需要C ++ 11。在这里查看它们:http://www.cprogramming.com/tutorial/functors-function-objects-in-c++.html
答案 1 :(得分:1)
因为基类中没有任何虚函数,所以运气不好。否则,您可以使用typeid *this
无论如何,您的函数应该在基类中是虚拟的,并在子类中重写。请记住:继承模型是一种关系,因此限制特定子类的服务违背了它的预期用途。更好地拥有基类的受限行为,并在某些子类中允许更多。
答案 2 :(得分:1)
你不想使用RTIA的地方经常使用的一个模式就是让类的枚举称为“typeid”,并为每个函数提供一个返回对象typeid的方法。这将让您知道您当前正在处理哪种类型(通过调用this-&gt; typeid)
但是,如果您不希望给定的类能够调用该函数,则更容易。覆盖该类中的函数并执行此类操作。但是,当我从相信的通用指针使用时,这将需要虚函数正常工作。
//override
return_type MyClass::MyFunction(ArgType arg)
{
if ( !condidtionsMet ) {
throw SomeException;
}
else {
return MyParentClass::MyFunction(arg);
}
}
答案 3 :(得分:0)
您可以尝试使用dynamic_cast
void A(){
if(dynamic_cast<child1>() == 0) {
//1. Throws exception if b < # ONLY when child1 calls
}
else
//2. Always executes code if child2 calls regardless of condition
}
}
但这是不好的做法,更好的是制作A()虚拟函数并覆盖child1和child2。
class parent {
public:
int b;
virtual void A() = 0;
virtual ~parent() {}
}
class child1 : public parent {
virtual void A() {
}
}
class child2 : public parent {
virtual void A() {
}
}
int main(){
child1 one;
child2 two;
one.A(); //This needs to throw exception under certain conditions
two.A(); //This will always execute
}