C ++确定哪个子类正在调用父函数

时间:2014-04-02 18:57:56

标签: c++ function class exception parent

好吧所以我无法在任何地方找到答案,这是我的第一篇文章,所以请善待。 基本上,如果某个子类在某些条件下调用父函数,我需要抛出异常,但另一个子类应始终能够执行该函数。

- 如果您想知道,它是一个带有储蓄和支票子类的帐户类的提款功能。储蓄具有最小余额(如果撤销导致其低于最小值,则抛出异常)但是检查没有最小值

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
}

任何人都有任何提示如何确定哪个子类正在调用该函数?

4 个答案:

答案 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

获取实际类的typeid

无论如何,您的函数应该在基类中是虚拟的,并在子类中重写。请记住:继承模型是一种关系,因此限制特定子类的服务违背了它的预期用途。更好地拥有基类的受限行为,并在某些子类中允许更多。

答案 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
}