views:

178

answers:

2

I have a code similar to the following:

class News {
public:
  virtual void get() = 0;
}

class Cnn : News {
  void get () {...}
}

class Msnbc : News {
  void get () {...}
}

class Bbc : News {
  void get () {...}
}


main ()
{
 News * news = new Cnn;
 news->get ()

 News * news = new Msnbc;
 news->get ()

 News * news = new Bbc;
 news->get ()
}

Instead of creating each sub-classes, what is the best way to store the sub-classes (Cnn, Msnbc...) and iterate over and get a news from all of the feeds (I can't use STL at a moment)

Thanks

+3  A: 

If you can't use STL then your best bet is to use an array of News*.

News*[] GetAllNews( int& count ) {
  News*[] arr = new News*[3];
  count = 3;
  arr[0] = new Cnn();
  arr[1] = new Msnbc();
  arr[2] = new Bbc();
  return arr;
}

int count;
News*[] arr = GetAllNews(count);
for ( int i = 0; i < count; i++ ) {
  arr[i]->get();
}

// Now for the awkward cleanup
for ( int i = 0; i < count; i++ ) {
  delete arr[i];
  arr[i] = NULL;
}
delete[] arr;
JaredPar
I know that many will disagree with me, but you (a) do at runtime what should've been at compile time and (b) being way too verbose.
Michael Krelin - hacker
@hacker, you went for a more static solution while I went for a more dynamic one. The dynamic one is necessarily more verbose.
JaredPar
That's the point - your code looks like it is translated from dynamic language -- c++ isn't your native, is it? ;-)Actually, I'd say you're too verbose for completely dynamic way too. Again - it is my opinion, which many will disagree with.
Michael Krelin - hacker
@hacker: I'd say that a gold badge in C++ qualifies JaredPar as a non-beginner in the language. Then again, he's not litb :P
David Rodríguez - dribeas
@hacker, how can you have a dynamically sized array (no-STL) and be less verbose? Barring some template insanity.
JaredPar
JaredPar, first, I see no reason to bar what you call template insanity (although where would I put it here?), but, anyway, on a second thought I think I'd take my word on verbosity for completely dynamic implementation back.
Michael Krelin - hacker
dribeas, golden badge in c++ means he's been upvoted by people who infer from my words he *is* a beginner in the language. So, badge signifies nothing at all - it's not Jared's fault on the other hand that he's got you and two of your upvoters for defenders ;-)And I have no idea what "litb" is. Even though I'm *not* a beginner in the language, English is not my native and will never be;-)
Michael Krelin - hacker
@hacker: I had to upvote your last comment for the humour value of "And I have no idea what 'litb' is"... :) litb's a guy on SO with a level of C++ knowledge that borders on scary. Some say he is half human, half template specialisation... :)
j_random_hacker
@JaredPar: Nothing verbose that I can see here, but I think your array declarations are a little off -- should be `News* arr[]` instead of `News*[] arr`, and the return type of `GetAllNews()` needs to change similarly.
j_random_hacker
j_random_hacker, ;-) Despite my registration date I'm here only for one month and don't really spend all the time on SO. Thanks for education - I thought it's yet another cause of PCMCIA (people can't memorize computer industry acronyms).And yes, I took back my words on verbosity for dynamic approach, it was just an impression. I don't think that severely insulted Jared, at the time of my first comment I considered his answer totally valid, anyway. I regret having commented on it.
Michael Krelin - hacker
Downvoting to get your attention re: array syntax (I'd fix it myself, but I can't be bothered figuring out the correct syntax for the declaration of `GetAllNews()`... :))
j_random_hacker
Isn't the correct syntax a mere `News**`?
Michael Krelin - hacker
@hacker: Yes you're right there. Since Jared is doing 2-level dynamic allocation, he needs a `News**` instead of an array-of-pointer-to-`News` -- otherwise the 2nd line in his snippet doesn't make sense.
j_random_hacker
Now that I've looked at the code again I know what verbosity bothers me ;-). I'd change the second line to `News **arr = new News*[count=3]`. For the sake of maintainability. Having to keep the list of assignments in sync with allocation count is enough pain, I wouldn't want to have to change the number twice.
Michael Krelin - hacker
A: 
News *n[] = { new Cnn(), new Msnbc(), new Bbc() };
for(News **p=n;p<&n[ sizeof(n)/sizeof(*n) ];++p) {
    (*p)->get();
    delete *p;
}
Michael Krelin - hacker
Why the downvotes? It maybe concise as answer, but it answers the question. The static approach is valid too, especially in smaller embedded systems that can't use the complete C++.
stefaanv
Come on guys, this is a good answer -- concise and correct. +1. (Would be nice to split the `sizeof` element-count trick into a separate inline function template for clarity mind you.)
j_random_hacker
Thanks guys.j_random_hacker, yes, in real life code that would make sense, but in the answer I think it gives better idea of what's going on. At least that was my motivation for embedding it here.
Michael Krelin - hacker
stefaanv, I actually had no idea what to add to the code here - it's so short that needs no comments that do not repeat the code itself. As for static approach, *in this particular case* I see no single reason to prefer dynamic over it. It is faster (well, not much, of course), easier to maintain, shorter...
Michael Krelin - hacker