I have a problem to access a base class member variable from a derived class thru开发者_JAVA技巧 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 << 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!!
// --- 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;
}
If SuffixableElement
is your interface, then StemmedSentence
must derive from it.
精彩评论