Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

c++ recursive class

22 views
Skip to first unread message

Luigino

unread,
Dec 21, 2009, 6:05:00 AM12/21/09
to
Hello everyone!!!

I'd need a little hint on this little question:

I have a xml file I want to navigate and I have a library to process
it. But I want also to manage that file as an object to make clear and
efficient code.
So I coded two class which one is like recursive as like as in this
example:

class B : public xmlnode
{
public:
B(xmlnode* member);

LPCSTR getattribute(....);
void setattribute(....);

xmlnode* Node(LPCSTR nodename, LPCSTR attributenodename, LPCSTR
attributetosearch);
};

class A : public xmldocument
{
public:
A(LPCSTR xmlfilename);

xmlnode* Node(LPCSTR nodename, LPCSTR attributenodename,
LPCSTR attributetosearch);
};

So I can do this:

A* xmlobject = new A(filenamexmlblahblah);
xmlobject->Node(....,....,...)->Node(...,...,...)->GetAttribute(...);

where next nodes are nodes inside a parent node...but I get this link
error:

error LNK2019: unresolved external symbol "public: class B *
__thiscall B::Node(....)" ....

what I could have missed?...
Even I'm just using a function that returns class node itself....

Thanks to everyone!
Ciao
Luigi

David Lowndes

unread,
Dec 21, 2009, 6:36:23 AM12/21/09
to
>where next nodes are nodes inside a parent node...but I get this link
>error:
>
>error LNK2019: unresolved external symbol "public: class B *
>__thiscall B::Node(....)" ....
>
>what I could have missed?...

You appear to have missed writing the B:Node method. You've got the
declaration of it in the header file, but no implementation.

Dave

Luigino

unread,
Dec 21, 2009, 6:45:53 AM12/21/09
to

I implemented the function in the .cpp as:

xmlnode* xmlnode::Node(LPCSTR nodename, LPCSTR attributenodename,
LPCSTR
attributetosearch)
{
....
}

but I still get that linker error....

Luigino

unread,
Dec 21, 2009, 7:04:16 AM12/21/09
to
BTW I typed wrong....

code is this:

class B : public xmlnode
{
public:
B(xmlnode* member);

LPCSTR getattribute(....);
void setattribute(....);

B* Node(LPCSTR nodename, LPCSTR attributenodename, LPCSTR
attributetosearch);

};

class A : public xmldocument
{
public:
A(LPCSTR xmlfilename);

B* Node(LPCSTR nodename, LPCSTR attributenodename,
LPCSTR attributetosearch);

};

B* B::Node(LPCSTR nodename, LPCSTR attributenodename,
LPCSTR
attributetosearch)
{
....

}

and I get that linker error...

David Lowndes

unread,
Dec 21, 2009, 7:17:07 AM12/21/09
to
>and I get that linker error...

I can't immediately see what's wrong from what you've mentioned, but
clearly the linker is telling you that it can't link in the B::Node
method.

Dave

Joseph M. Newcomer

unread,
Dec 21, 2009, 1:18:51 PM12/21/09
to
See below...

On Mon, 21 Dec 2009 03:05:00 -0800 (PST), Luigino <npu...@rocketmail.com> wrote:

>Hello everyone!!!
>
>I'd need a little hint on this little question:
>
>I have a xml file I want to navigate and I have a library to process
>it. But I want also to manage that file as an object to make clear and
>efficient code.
>So I coded two class which one is like recursive as like as in this
>example:
>
>class B : public xmlnode
>{
>public:
> B(xmlnode* member);
>
> LPCSTR getattribute(....);

***
The use of LPCSTR seems a bit odd in an MFC program; CString would be better
****


> void setattribute(....);
>
> xmlnode* Node(LPCSTR nodename, LPCSTR attributenodename, LPCSTR
>attributetosearch);
>};
>
>class A : public xmldocument
>{
>public:
> A(LPCSTR xmlfilename);
>
> xmlnode* Node(LPCSTR nodename, LPCSTR attributenodename,
>LPCSTR attributetosearch);
>};
>
>So I can do this:
>
>A* xmlobject = new A(filenamexmlblahblah);
>xmlobject->Node(....,....,...)->Node(...,...,...)->GetAttribute(...);
>
>where next nodes are nodes inside a parent node...but I get this link
>error:
>
>error LNK2019: unresolved external symbol "public: class B *
>__thiscall B::Node(....)" ....
>
>what I could have missed?...

****
So did you define the Node() function? You declared it, but did you actually put it in
the .cpp file?
****


>Even I'm just using a function that returns class node itself....

****
See above. You probably didn't define it!
****


>
>Thanks to everyone!
>Ciao
>Luigi

Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

Joseph M. Newcomer

unread,
Dec 21, 2009, 1:20:08 PM12/21/09
to

****
Why are you declaring B* B::Node in A? That doesn't seem to make sense.
joe
***


>
>and I get that linker error...

Luigino

unread,
Dec 22, 2009, 6:34:49 AM12/22/09
to
HI Joe...

i'll explain better my situation: I have a XML file and I'm using
tinyxml to elaborate it... so I wanted just to navigate nodes and to
set/get attributes in this way:

MyDocument->Node(nodename, attributenodename, attributetosearch)->Node
(nodename, attributenodename, attributetosearch)->GetAttribute
(attributename);

so I created first class for the node MyNode:

class MyNode : public TiXmlNode
{
public:
MyNode() { };

LPCSTR GetAttribute( LPCSTR attributename) { blah blah blah
return LPCSTR;} ;
void SetAttribute(LPCSTR attributename, LPCSTR attributevalue)
{blah blah blah };

MyNode* Node( LPCSTR nodename, LPCSTR attributenodename,
LPCSTR attributetosearch )
{ blah blah blah };
};

then I created second class for the document MyDocument so it would
already see MyNode:

class MyDocument : public TiXmlDocument
{
MyDocument(LPCSTR filename) { blah blah blah };

MyNode* Node( LPCSTR nodename, LPCSTR attributenodename,
LPCSTR attributetosearch )
{ MyNode::Node(nodename, attributenodename,
attributetosearch); };
};

so each Node call would return a new node to navigate inside the node
itself...but looks like it doesn't compile correctly... How it should
be?...

Thanks
Ciao
Luigi

David Wilkinson

unread,
Dec 22, 2009, 9:11:56 AM12/22/09
to

In class MyDocument you have

MyNode* Node( LPCSTR nodename, LPCSTR attributenodename,
LPCSTR attributetosearch )
{
MyNode::Node(nodename, attributenodename, attributetosearch);
}

Firstly, there is no return quantity in your definition. Secondly, you are
calling a non-static method of Node without an object.

In future, if you are having linker errors, it would be good if you could post
actual code that compiles.

--
David Wilkinson
Visual C++ MVP

Luigino

unread,
Dec 22, 2009, 10:55:41 AM12/22/09
to
Well, in .H file I put:

#include "tinyxml/tinyxml.h"

class documentTinyNode : public TiXmlNode
{
public:
documentTinyNode(); // CTOR object TiXmlNode
~documentTinyNode() { };

LPCSTR GetAttribute( LPCSTR attributename ) { return ToElement
()->Attribute( attributename ); } // function class returns
attribute
void SetAttribute( LPCSTR attributename, LPCSTR
attributevalue ) { ToElement()->SetAttribute( attributename,
attributevalue ); } // function class sets attribute

documentTinyNode* Node( LPCSTR nodename, LPCSTR
attributenodename, LPCSTR attributetosearch ) // function class
returns new node
{
FirstChild(nodename);
LPCSTR currentnodename = ToElement()->Attribute
(attributenodename);

while ( (currentnodename != NULL) && (strcmp
(currentnodename, attributetosearch) != 0) ) {
IterateChildren(nodename , this);
currentnodename = ToElement()->Attribute
(attributenodename);
}
return ( (currentnodename != NULL) ? this : NULL );
}
};

class documentTinyXML : public TiXmlDocument
{
public:
documentTinyXML( LPCSTR xmlfilename ); // CTOR object
TiXmlDocument
~documentTinyXML() { };

documentTinyNode* Node( LPCSTR nodename, LPCSTR
attributenodename, LPCSTR attributetosearch ) // function returns
object class TiXmlNode
{
documentTinyNode::Node(nodename, attributenodename,
attributetosearch);
}); // function returns object class TiXmlNode
};

indeed in .CPP file I put:

documentTinyXML::documentTinyXML( LPCSTR xmlfilename )
{
if (!LoadFile( xmlfilename ))
AfxGetMainWnd()->MessageBox(_T("Error! Can't load xml
configuration file!\nIt could be not present or broken."), _T("MFC
Analyzer GUI"), MB_ICONSTOP | MB_OK);
}

void Ctest_tinyxmlDlg::OnBnClickedButton1()
{
//<?xml version="1.0" ?>
//<analyzer>
// <module name="system-manager">
// <sentence header="enableModules">
// <row-info name="system-manager"
value="1" />
// <row-info name="input-manager"
value="1" />
// <row-info name="output-manager"
value="1" />
// </sentence>
// </module>
// <module name="input-manager">
// <sentence header="output-type">
// <row-info name="out" value="1"
description="whatever-it-is" />
// </sentence>
// </module>
// <module name="output-manager">
// <sentence header="output-type">
// <row-info name="out" value="1"
description="whatever-it-is" />
// </sentence>
// </module>
//</analyzer>

documentTinyXML* xmldocument = new documentTinyXML
( "example.xml" );
LPCSTR pValue = xmldocument->Node("module","name","system-
manager")->Node("sentence","header","enableModules")->Node("row-
info","name","system-manager")->GetAttribute("value");
GetDlgItem(IDC_EDIT1)->SetWindowText( (LPCTSTR)pValue );
}

As you can see I’d like to start from TiXmlDocument’s type member
variable, getting deeper nodes to decide where to navigate since I
could have same sentences in different sublevels… how I could do
that?...

Thanks
ciao
Luigi

Joseph M. Newcomer

unread,
Dec 22, 2009, 9:54:48 PM12/22/09
to
I haven't looked at tinyxml, but most versions of xml have a generic node type, and any
"meaning" is extracted from the tag. That is, if I have a node
<tag:node1>
then I ask "what is your tag, what is your type?" and then I can set and get attributes
for that type of node. So there is only one type of generic node.
joe

0 new messages