A few questions

Hey everyone, first post but I'm an avid crawler of the forums here =P

I have a few questions to see if any C++ gurus out there can help me with

1) Is it possible to create a multi type array without using lets say void* arrays?
I'm trying to make an array full of objects that are of different classes as a sort of TaskList that will update all objects on an event trigger at once rather than creating a massive list of calls to the update functions.
So far I'm thinking making an array of type void* full of addresses that can then dereference a commonly named update function with a for loop. I can't give you code because I have no written it yet but I'll keep you posted.

2) Is it possible for a function or class to get the name of its calling function or class?
I was trying to make an exception class but it would help a lot if I could just throw and catch and have the exception class know who threw and tell the catcher. Also lacking in code here and I would prefer it not be an argument so that its more generic but I'll settle for an argument if need be.

3) I'm having a little trouble understanding the various documentation of exceptions in C++.
If a function has a throw attached to it
void myfunc(void) throw(Exception)
Does throw; automatically throw the above referenced exception or do I still have to refer to the correct exception class?
1) Best to avoid void* if possible. You could use boost::any, which can still hold any type, but is somewhat safer than using void*. It has a special casting function for safe casting from type to type.

Alternately, you could have an abstract base class, and have an array of pointers to it. Then derive from it to implement the particular functionalities. (I'm not sure I've explained this last bit very well...)

2) Not directly I don't think. Perhaps you could have a global std::stack<std::string> which you would use to keep track of this?

3) Those are called exception specifications. Superficially, what it means is that myfunc() might throw the exception "ExceptioN", but it won't throw anything else. However, it does not work like this. Exception specifications make the compiler do all kinds of horrible things, and in general there is no benefit, so do not use exception specifications in general. There are, of course, a few subtleties, but that's basically it.
Further reading: http://www.gotw.ca/publications/mill22.htm
Last edited on
Thanks for the reply Xander
1) I wanted to avoid using many external libraries but I was already considering including Boost. I did not know about that little add-in so I think that makes Boost a solid addition to my project. I'm not sure how good my colleges (also students and new to C++) are at reading documentation and existing code but hopefully it works out.

2) You would think throw would hand out useful information like that...

3) Wow I fell for one of the apparently common pitfalls of C++ documentation lol
Thanks for the check on that. Last thing I want is a lack of portable code.
Here are some examples, not tested of course...

1) From the description above, it sounds like you're after polymorphism. You can create a container (or array) of base class pointers and use the uniform base class interface for derived objects. If that is not what you're after, Boost.Any or Boost.Variant may be of interest.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Base
{
public:
    virtual ~Base() {}
    virtual void f() = 0;
};

class One : public Base
{
public:
    virtual void f() { std::cout << "One::f()" << std::endl; }
};

class Two : public Base
{
public:
    virtual void f() { std::cout << "Two::f()" << std::endl; }
};

//...

vector< Base * > c; // remember to delete these
c.push_back( new One() );
c.push_back( new Two() );
for( vector< Base *>::iterator i = c.begin(); i != c.end(); ++i ) {
    i->f(); // call f() for whichever derived object
}


2) You would have to insert the calling information into the exception explicitly. For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class FromWhereException : public virtual std::exception
{
public:
    FromWhereException( const std::string & from ) : from( from ) {}
    virtual const char* what() const { return std::string( std::string( "Called from: " ) + from ).c_str(); }
private:
    std::string from;
};
//...
try {
    throw FromWhereException( __FUNCTION__ );  // __FUNCTION__ is a common but non-standard compiler extension
} catch( const FromWhereException & e ) {
    std::cout << e.what() << std::endl;    
}
Topic archived. No new replies allowed.