質問

Alright so I couldn't find the answer anywhere, and this is my first post so please be kind. Basically i need to have an exception thrown if a certain child class calls a parent function under certain conditions, but another child class should always be able to execute the function.

--If you're wondering, its a withdraw function for an account class with savings and checkings child classes. Savings has a minimum balance (throw exception if withdraw causes it to go below minimum value) but checking has no minimum

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
}

Anyone have any tips how to determine which child class is calling the function?

役に立ちましたか?

解決 2

Because you don't have any virtual functions in the base class, you are just out of luck. Otherwise you could get the typeid of the actual class using: typeid *this

Anyway, your function should be virtual in the base class and overridden in the child classes. Please remember: inheritance models an is-a relationship, so restricting service for specific child-classes goes against it's intended use. Better have the restricted behavior for the base class, and allow more in some child classes.

他のヒント

There is no easy way to do this without circular dependencies. Probably the simplest way to do it would be by overloading the function in each class:

class Child1 : public Parent
{
   void A(int v) 
   {
      if (this->b > v)
      {
         throw 1;
      }
      else
      {
         Parent::A(v);
      }
      return;
   }
}

You could also make the function pure virtual in the base class to force all of the children override the function with their own copy.

class Parent
{
   virtual void A() =0;
}

class Child1 : public Parent
{
   void A(int v) 
   {
      if (this->b > v)
      {
         throw 1;
      }
      else
      {
         <<do something>>
      }
      return;
   }
}

Alternatively, you could use Functors, but these can get very complicated and require C++11. Check them out here: http://www.cprogramming.com/tutorial/functors-function-objects-in-c++.html

Where you don't want to make use of RTIA One pattern often used is to have an enumeration for the classes call it say "typeid", and give each function a method which returns the objects typeid. This will let you know which type you are currently working on (by calling this->typeid)

However if you don't want a given class to be able to call the function it's even easier. Override the function in that class and do somehting like this. However this would require virtual functions to work properly when used from a generic pointer I believe.

//override
return_type MyClass::MyFunction(ArgType arg)
{
    if ( !condidtionsMet ) {
        throw SomeException;
    } 
    else {
        return MyParentClass::MyFunction(arg);
    }

}

You can try to use 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
   }  
}

But it is bad practice, much better is to make A() virtual function and override it for child1 and 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
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top