0

I`m trying to create an example of 2 classes that each class contain a field of the other class, for example(header file):

class Sentence{

private:
     int wordNum;
     Word words[200];
public:..
};

class Word{

private:
        char *word;
        Sentence  sentences[100];
public:..
}

when I`m doing that Word Words[200] not defined, how the order of the class need to be that both of classes will be defined? because it affect on the public methodes.
I would like to get some advice what to do, Thanks!

Ofir Attia
  • 1,237
  • 4
  • 21
  • 39
  • Think about this again. It's like `struct X { X x; }`. In other words, what's the content of a box that contains itself? – Kerrek SB Jul 11 '13 at 23:18
  • possible duplicate of [Resolve circular dependencies in c++](http://stackoverflow.com/questions/625799/resolve-circular-dependencies-in-c) – Nemo Jul 11 '13 at 23:19
  • The only way to "fix" this is to rethink your hierarchy. – Borgleader Jul 11 '13 at 23:19

4 Answers4

1

This is impossible. A Sentence must contain 200 instances of Word, and therefore 20,000 instances of Sentence; just try to calculate its size.

A Sentence can contain a Sentence*, or a vector<Sentence>, or any number of other things that lead to other Sentences, but not an array of Sentences. You must revise your design.

Beta
  • 96,650
  • 16
  • 149
  • 150
1

You can't. Both of your classes are contained inside each other, which is nonsense.

What you probably want is to hold pointers to each other. That is:

class Sentence
    ...
    Word* words[200];
    ...
};

class Word {
    ...
    Sentence* sentences[100];
    ...
};
DanielKO
  • 4,422
  • 19
  • 29
  • It compiles but it introduces a bunch of problems along with memory handling. I don't want to offend anyone but I think that's not a good piece of advice here. – Pixelchemist Jul 11 '13 at 23:35
  • We don't know anything else about the problem other than "I tried this, it didn't compile". I can go ahead and point out that your proposed answer is logically flawed, as your vector will hold copies of the objects instead of referencing, which could be what was intended. No point in being pedantic over something that was not even specified nor asked. – DanielKO Jul 11 '13 at 23:40
  • Neither did I downvote your answer, nor is may remark _pedantic_ or offensive. Along with the question, the OP "_specified_" that he's presumably a beginner. Stop complaining please! Enabling relationality in my example is a matter of introducing a single `*` (or a shared_ptr or whatever there may fit)... Tidy handling of a combination of arrays and pointers is hard to achieve. Even if a certain solution may be the one "requested" by the OP there's no point in NOT giving a hint towards possible problems of it. (There's a chance that this is the best fit but imho it's unlikely.) – Pixelchemist Jul 12 '13 at 00:29
0

You can't do it this way. Think about it - what would the size in bytes of Sentence instance be? Clearly, it must be at least 200 times the size of Word. Then what should the size of Word be? At least 100 times the size of Sentence. So sizeof(Sentence) > sizeof(Word) > sizeof(Sentence). Can you see what's wrong with this picture?

You can have Sentence hold a Word* or vector<Word>, or have Word hold Sentence* or vector<Sentence>, or both. Once you do that, then forward declarations, as suggested by @McGarnagle, would work.

Igor Tandetnik
  • 50,461
  • 4
  • 56
  • 85
-1

Let's imagine this would compile.

You Word has 100 sentences where each Sentence has 200 words (20000 Words here), each of which has 100 sentences (2000000 Sentences here), each of which has 200 words (400000000 Words), each of which ...

I think I may stop here. You'll probably realize that this is not what you wanted to have.

You need to think again about your structure and you should take into account what a user or maintainer of such code would probably expect.

A sentence that contains several words -> Well ok that's logical.
A word that contains sentences? -> Why should a word ever contain sentences? Noone will ever expect this to be the case.

Furthermore: If you don't have a project that handles only sentences that always contain exactly 200 Words you may well consider using a dynamic memory structure like std::vector.

class Sentence
{
private:
   int wordNum;
   std::vector<Word> words;
public:
   ...
};


If relationality is required you're of course free to use pointers.

If you want some kind of automated lifetime (if you have C++11 capability at hand) you could for example use a vector of std::shared_ptr from sentences to words. -> Each sentences containing a specific word has its own shared ptr to that word object. If all sentences with a specific word go out of scope / are destroyed, the word will be removed, too.

I'd still recommend to stick to something that enables you to make use of RAII.

Pixelchemist
  • 24,090
  • 7
  • 47
  • 71
  • A word might be holding references to sentences that share it; in that case, having sentences holding their own words is wrong, as they are not sharing words. See, I can be pedantic too. – DanielKO Jul 11 '13 at 23:42
  • I guess the OP probably knows better (than you) about the relationality of what he wants to achieve and his example had sentences that HOLD their words so I didn't diverge my solution from it. But yes it may still not be what OP inteded to do. – Pixelchemist Jul 12 '13 at 00:35