Few Basic Questions

1. Can Pure Virtual Functions Be Overloaded?

I know we can (must) override Pure virtual functions in the derived class but can we overload them? I mean if we have the something like virtual void f()=0 in base class, can I use void f(int){//do something} in derived class?

2. Can someone please direct me to a link/article where from I can learn what happens internally during the "stack unwinding" process? If not, atleast what happens internally when an exception is thrown?

3. I been thinking that throw exception from CTOR is allowed. I mean I am thinking that the below snippet is allowed.
1
2
3
4
class A
{
A(){throw 10;}
};

My question is what will happen to this thrown exception? Who will catch it?

4. The best practices say that throwing exception from DTOR is NOT safe/recommended. Consider the code -

1
2
3
4
5
6
7
8
9
10
11
12
class A
{
A();
~A();
};

int main()
{
A a;
a->f();//Assume that f() DOES NOT throw any exception
delete a;
}


Given the fact that f() does not throw any exception, can I throw an exception from the DTOR? Is it OK? If not, what will it cause?

Please explain in easy terminologies. Thanks very much for your time!
Last edited on
1. Functions with the same name but with different parameters (overloaded) are independent from one another. So you can not override and overload at the same time. The compiler will still ask for an override of the pure virtual function.

2. This gives *some* information: http://www.parashift.com/c++-faq-lite/exceptions.html

3. You, the programmer will catch the exception.
1
2
3
4
5
6
7
8
9
10
11
12
13
int main()
{
    try
    {
        MyClass m;
    
        m.do_stuff();
    }
    catch(std::exception& e)
    {
        std::cout << e->what() << std::endl;
    }
}



4. http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.3
Last edited on
1. Can Pure Virtual Functions Be Overloaded?

Sure, same as non-pure functions. But you will still have to implement the virtual function to get a non-abstract class.

That's consistent with the fact that overloaded non-pure virtual functions will not get called if someone calls to the base class virtual function.

1
2
3
4
5
6
7
8
9
10
11
12
struct Base {
  virtual void foo() { cout << "I will be called";
};
struct Der : Base {
  // overloads, but not override.
  virtual void foo(int i) { cout << "I will not be called"; }
};
int main() {
  Der d;
  Base* b = &d;
  b->foo();
}


(If you make Base::foo pure virtual, you get a compile error in first line of main, as Der would be still abstract.)


2. Can someone please direct me to a link/article where from I can learn what happens internally during the "stack unwinding" process? If not, atleast what happens internally when an exception is thrown?

You could read the standard directly. It's not THAT hard, if you get used to the language there. Google for "ANSI ISO IEC 14882". It's probably somewhere under chapter 15 "exceptions".

3. I been thinking that throw exception from CTOR is allowed. I mean I am thinking that the below snippet is allowed.

Not only "allowed", but constructors are one of the main reason they invented exceptions ;) (Since you can't return an error code from a constructor).

The exception is catched normally by the next higher catch block. Note, that the objects destructor will not be called if the constructor exited with an exception. Writing an exception-safe constructor is one of the major challenges in writing exception-safe code at all. (Destructors of member variables that have been successfully initialized are called. Note that this only holds for objects. A plain pointer as member variable doesn't have a destructor).

For this reason (destructor not called), a lot of people recommend not to throw exceptions in constructors. But in fact, it's much less recommended than the no-throwing destructor thingie.


4 The best practices say that throwing exception from DTOR is NOT safe/recommended.

This relates to your "stack-unwinding" question. You may throw an exception in a destructor only, if the destructor has not been called in a stack-unwinding process. But many destructors are actually there BECAUSE you want to clean up stuff in case of stack unwinding (this idiom is called RAII). So it is safe to recommend: Never ever throw in a destructor.

If you throw an exception while you are in stack unwinding, your programm just terminates immediately (aborting any destructors, any threads, ANYTHING. Poof!).

Ciao, Imi.
Last edited on
Galik (88) - Thanks very much for your reply. That Parashift link was helpful. It replies to most of other questions I had.

Imi - Thanks for your explanation. I downloaded that ANSI ISO IEC 14882 pdf containing around 1357 pages. Like you said, I may take some time to get adopted to that style of language though. I think I will rather buy Bjarne's C++ Programming Language bible. That should educate me a lot of the basics, I hope.
Topic archived. No new replies allowed.