0

I have a problem to access a base class member variable from a derived class thru a interface containing 2 virtual functions. The main purpose is that I need to work with these classes at 2 different programn stages. First stage is to fill an array with text snippets / sentences thru the ArrayStemmedSnippet class The second stage, at a later point in the program, is getting items from the sentences array/snippet array defined in the base class thru the SuffixableElement interface class.

I have the strong feeling I am missing some basics here. I think there is a basic design or logic error. Also i have to admit, that I am not a C++ pro, means I am still a C++ beginner, So please bear with me....

Let me show you the code I have:

The class definition:


using namespace std;

// ---  class represents a stemmed term of a StemmedSentence object
class StemmedTerm {
private:
 string _word;
 string _stemmed;
public:
 StemmedTerm(string word, string stemmed);
 ~StemmedTerm();
 // --- Implementation of StemmedTerm interface
 string getTerm(); 
 string getStemmed(); 
};

class StemmedSentence;
class SuffixableElement;

// --- a snippet containing stemmed sentences
class ArrayStemmedSnippet {
friend class StemmedSentence;
public:
 ArrayStemmedSnippet();
 ArrayStemmedSnippet(Array snippetTerms);
 ~ArrayStemmedSnippet();
 SuffixableElement * getSentence(int n);
 int size() const; 
private:
 Array snippet;
 Array sentences;
};

// --- a stemmed sentence from ArrayStemmedSnippet
class StemmedSentence : public ArrayStemmedSnippet {
public:
 StemmedSentence(ArrayStemmedSnippet *p);
 StemmedSentence(const int start, const int end);
 virtual ~StemmedSentence(); 
 virtual void * get(int index) const; 
 virtual int size() const; 
private:
 int _start;
 int _end;
 ArrayStemmedSnippet *parent;
};

// --- interface to access a stemmed sentence and its size 
class SuffixableElement {
public:
 virtual ~SuffixableElement() = 0;
 virtual void * get(int index) const = 0;
 virtual int size() const = 0;
};

The implementation:


using namespace std;

StemmedSentence::StemmedSentence(const int start, const int end) : _start(start), _end(end) { } StemmedSentence::StemmedSentence(ArrayStemmedSnippet *p) : parent( p ) { } StemmedSentence::~StemmedSentence() { } // --- implementation interface SuffixableElement void * StemmedSentence::get(int index) const { if (index == (size() - 1)) { return NULL; // --- End of string (sentence) } // get the stemmed term from snippets array in ArrayStemmedSnippet class // is null, because array is not accessable thru the Suffixable iFace / eg not defined return snippet[ _start + index ]; } // --- implementation interface SuffixableElement int StemmedSentence::size() const { return _end - _start + 2; }

// --- add array of snippet terms to sentences. NULL represents end of sentence ArrayStemmedSnippet::ArrayStemmedSnippet() { } ArrayStemmedSnippet::ArrayStemmedSnippet(Array snippetTerms) : snippet( snippetTerms ) { int index = 0; for (int i = 0; i < snippetTerms.getLength(); i++) { if (snippetTerms[ i ] == NULL) { sentences.append( new StemmedSentence(index, i - 1 )); index = i + 1; } } } ArrayStemmedSnippet::~ArrayStemmedSnippet() { for (int i = 0; i < sentences.getLength(); i++) { delete sentences[i]; } } int ArrayStemmedSnippet::size() const { return sentences.getLength(); } // --- returns n-th sentence of this snippet SuffixableElement * ArrayStemmedSnippet::getSentence(int n) { StemmedSentence( this ); // --- just a try: try passing base instance to derived class return (SuffixableElement*)sentences[ n ]; }

The main body:


int main() {
    // Sentence 1:
    Array stemmed;
    StemmedTerm *st1 = new StemmedTerm( "Mouse", "Mouse" );
    StemmedTerm *st2 = new StemmedTerm( "ate", "ate" );
    StemmedTerm *st3 = new StemmedTerm( "cheese", "cheese" );

    stemmed.append( st1 );
    stemmed.append( st2 );
    stemmed.append( st3 );
    stemmed.append( NULL ); // ---- end of snippet sentence

    // Sentence 2: 
    StemmedTerm *st21 = new StemmedTerm( "Cat", "Cat" );
    StemmedTerm *st22 = new StemmedTerm( "ate", "ate" );
    StemmedTerm *st23 = new StemmedTerm( "cheese", "cheese" );
    StemmedTerm *st24 = new StemmedTerm( "too", "too" );

    stemmed.append( st21 );
    stemmed.append( st22 );
    stemmed.append( st23 );
    stemmed.append( st24 );
    stemmed.append( NULL ); // ---- end of snippet sentence
    //  ok -- one stemmedsnippet with 2 sentences
    ArrayStemmedSnippet ass( stemmed );

    // do some sother stuff ... later in the program ....

    // --- get elements and size info thru SuffixableElements interface 
    SuffixableElement *currentElement = (SuffixableElement *)ass.getSentence(1);
    cout << "cur. element size=" << currentElement->size() << endl;
    StemmedTerm *st = (StemmedTerm*)currentElement->get(2, ass);
    string str = st->toString();
    cout < "second word is=" << str <&lt endl;

    delete st1;
    delete st2;
    delete st3;

    delete st21;
    delete st22;
    delete st23;
    delete st24;

return 1;
} 

I skipped some function from above (toString() and other not relevant fct) to keep the code as short as possible.

So the main problem is when I call

SuffixableElement * currentElement = (SuffixableElement *)ass.getSentence(1);

// --- this works fine! cout << "cur. element size=" << currentElement->size() << endl;

// --- does not work, because snippet array of base class is uninitalized coming thru the // --- interface .... // --- Also passing the instance of the base class ArrayStemmedSnippet with the // --- getSenctence() Fct does not help. StemmedTerm * st = (StemmedTerm *)currentElement->get(2); // should return "cheese" string str = st->toString(); cout << "str=" << str << endl;

What do I have to to that the snippet array is accessable thru the get(int index) call with the SuffixableElement interface. The size() Fct is no problem, since I instanciated the derived class and access local members _start/_end. Also StemmedSentence class as a nested class within ArrayStemmedSnippet is not working, unlike Java (I think) C++ wont let me access objects of ArrayStemmedSnippet like that.So I am sure I have some basic misunderstanding.

What I am missing???

Any help is greatly appreciated!!

Andreas W. Wylach
  • 723
  • 2
  • 10
  • 31
  • Honestly, it is not quite clear what you're trying to achieve. The code doesn't compile at all. Could you please be more detailed (in plain English) what the concept is? – Kerido Mar 05 '10 at 08:29
  • I want to be able to access the array "snippets" defined in the base class ArrayStemmedSnippet thru the SuffixableElement Interface. But when I use the Interface with SuffixableElement *currentElement = (SuffixableElement*)ass.getSentence(1); to fetch the 2nd sentence from sentences array and try a currentElement->get(2) to get the 3rd StemmedTerm (3rd word) from it fails, because the array in the base class is null. Somehow clear, but I try to find a way to get access thru that interface. I need that interface access to the array process the single terms in the snippet array. – Andreas W. Wylach Mar 05 '10 at 14:40

2 Answers2

1
// --- returns n-th sentence of this snippet
SuffixableElement* ArrayStemmedSnippet::getSentence(int n) {
    // ...
    return (SuffixableElement*)sentences[ n ];
}

'sentences' is an array of objects of the StemmedSentence class. StemmedSentence is not derived from SuffixableElement, that is it does not provide that interface.

Try the following:

class StemmedSentence : public ArrayStemmedSnippet, public SuffixableElement {
    // ...
};

and

SuffixableElement* ArrayStemmedSnippet::getSentence(int n) {
    StemmedSentence* sentence = sentences[ n ];
    sentence->setParent(this);
    return sentence;
}
Corwin
  • 575
  • 2
  • 9
  • Way before when I try to print out a snippet[ ] array item within the get() Function in StemmedSentence class, the array is NULL, because I instanciated from the interface side. It is simply not visible from SuffixableElement Interface. All the entered data done by ArrayStemmedSnippet ass( stemmed ); is not visible. I think I have some basic misunderstanduing here, I just do not get it .... – Andreas W. Wylach Mar 05 '10 at 15:34
  • Scroll down the first code window of my main post (class definition) It is there as the last entry .... – Andreas W. Wylach Mar 05 '10 at 15:52
  • Well, which classes do implement this interface? – Corwin Mar 05 '10 at 15:58
  • That is the StemmedSentence Class, see "virtual void * get(int index)" and the "". get returns a single StemmedTerm object out of the StemmedSentence Object, size returns the size of the StemmedSentence object. I'll try your suggestion now ... – Andreas W. Wylach Mar 05 '10 at 16:39
  • I just wonder if setParent() is not the same as calling StemmedSentence(this) constructor? This seems not not work so does not setParent(this) by setting the StemmedSentence *parent variable. How did you implement setParent() in in StemmedSentence class? – Andreas W. Wylach Mar 05 '10 at 16:50
  • My bad .. it works!! Seems like the way setting the ArrayStemmedSnippet Object in getSentence did it. Thanks Corwin! I can continue the development :-) – Andreas W. Wylach Mar 05 '10 at 17:02
0

If SuffixableElement is your interface, then StemmedSentence must derive from it.

Kerido
  • 2,930
  • 2
  • 21
  • 34