Transferring Structure variables?(simple problem)
I'm trying to finish a problem for data structures where I count nodes from a node tree.
The problem is, I have to use structures for variables, and the variable types won't transfer over. This is my test program to test the function:
PHP Code:
#include<iostream>
#include "tree.h"
using namespace std;
int main()
{
nodeType<int> *root;
nodeType<int> *buddy;
binaryTreeType <int> test;
root=new nodeType<int>;
root->key_value=20;
root->left=NULL;
root->right=NULL;
buddy=root;
buddy->left=new nodeType<int>;
buddy->left->key_value=5;
buddy->left->left=NULL;
buddy->left->right=NULL;
buddy->right=new nodeType<int>;
buddy->right->key_value=5;
buddy->right->left=NULL;
buddy->right->right=NULL;
buddy=root;
int c= test.nodeCount(buddy); //problem occurs here
cout<<"The are "<<c<<" nodes in this tree"<<endl;
delete root;
delete buddy;
return 0;
}
and here is the header file:
PHP Code:
template<class elemType>
struct nodeType
{
int key_value;
nodeType<elemType> *left;
nodeType<elemType> *right;
elemType info;
nodeType<elemType> *llink;
nodeType<elemType> *rlink;
};
template<class elemType>
class binaryTreeType
{
public:
const binaryTreeType<elemType>& operator=(const binaryTreeType<elemType>&);
bool isEmpty();
void inorderTraversal();
void preorderTraversal();
void postorderTraversal();
int treeHeight();
int treeNodeCount();
int treeLeavesCount();
void destroyTree();
binaryTreeType(const binaryTreeType<elemType>& otherTree);
binaryTreeType();
~binaryTreeType();
protected:
nodeType<elemType> *root;
private:
void copyTree(nodeType<elemType>* &copiedTreeRoot, nodeType<elemType>* otherTreeRoot);
void destroy(nodeType<elemType>* &p);
void inorder(nodeType<elemType> *P);
void preorder(nodeType<elemType> *p);
void postorder(nodeType<elemType> *p);
int height(nodeType<elemType> *p);
int max (int x, int y);
int nodeCount(nodeType<elemType> *p); //problem occurs here
int leavesCount(nodeType<elemType> *p);
};
I thought keeping the same structures variable "nodeType" would work. But it doesn't, it says this for the error:
c:\documents and settings\j\my documents\c++\lab\project 1 question 4\test3\test3\question1test.cpp(30) : error C2248: 'binaryTreeType<elemType>::nodeCount' : cannot access private member declared in class 'binaryTreeType<elemType>'
with
[
elemType=int
]
c:\documents and settings\j\my documents\c++\lab\project 1 question 4\test3\test3\tree.h(41) : see declaration of 'binaryTreeType<elemType>::nodeCount'
with
[
elemType=int
]
any help would be much appreciated, I'm so close to solving this problem.
-thanks in advance pyromonki.
Re: Transferring Structure variables?(simple problem)
Your nodeCount function is private which means it can only be accessed by member functions of that class. Trying to access it from main() won't work. Make it public.
Re: Transferring Structure variables?(simple problem)
Quote:
Originally Posted by
pyromonki
I thought keeping the same structures variable "nodeType" would work. But it doesn't, it says this for the error:
c:\documents and settings\j\my documents\c++\lab\project 1 question 4\test3\test3\question1test.cpp(30) : error C2248: 'binaryTreeType<elemType>::nodeCount' : cannot access private member declared in class 'binaryTreeType<elemType>'
with
[
elemType=int
]
c:\documents and settings\j\my documents\c++\lab\project 1 question 4\test3\test3\tree.h(41) : see declaration of 'binaryTreeType<elemType>::nodeCount'
with
[
elemType=int
]
any help would be much appreciated, I'm so close to solving this problem.
-thanks in advance pyromonki.
You were given the solution, but It's strange that you are writing template code (intermediate to advanced C++), but couldn't solve a beginner error such as functions being private, public, or protected.
Hopefully you are not just copying this code from somewhere without learning C++ and understanding eveything you've learned.
Regards,
Paul McKenzie
Re: Transferring Structure variables?(simple problem)
I see no insertion or erasure methods in that binaryTreeType class. However, the fact that root is declared protected suggests that a derived type may be intended to supply those methods.....and most likely do everything else. I think "binaryTreeType" isn't intended to ever be used directly, but merely act as a base class. I'm surprised it isn't pure virtual.
treeNodeCount() would probably do what you want, but since that tree won't have anything in it, I guarantee you it'll return 0.
Re: Transferring Structure variables?(simple problem)
Quote:
Originally Posted by
Paul McKenzie
You were given the solution, but It's strange that you are writing template code (intermediate to advanced C++), but couldn't solve a beginner error such as functions being private, public, or protected.
Hopefully you are not just copying this code from somewhere without learning C++ and understanding eveything you've learned.
Regards,
Paul McKenzie
You got it right, the books problem told me to copy the program as is. I wouldn't have made such an advanced class to do all this, since I flat out don't understand them all that well.
The book doesn't explain templates very well either, and also, they put the nodeCount() function in the public area, which is why I was so reluctant to move it.
so please excuse my ignorance, I'm trying my best to understand template classes.
I appreciate your help guys.
I have one more problem, the program will compile but I can't create the .exe because I'm accessing nodeType, and binaryTreeType from the class in the main function.
the error says this:
Code:
question1test.obj : error LNK2019: unresolved external symbol "public: __thiscall binaryTreeType<int>::~binaryTreeType<int>(void)" (??1?$binaryTreeType@H@@QAE@XZ) referenced in function _main
question1test.obj : error LNK2019: unresolved external symbol "public: int __thiscall binaryTreeType<int>::nodeCount(struct nodeType<int> *)" (?nodeCount@?$binaryTreeType@H@@QAEHPAU?$nodeType@H@@@Z) referenced in function _main
question1test.obj : error LNK2019: unresolved external symbol "public: __thiscall binaryTreeType<int>::binaryTreeType<int>(void)" (??0?$binaryTreeType@H@@QAE@XZ) referenced in function _main
once again I can't thank you guys enough for your help. And if you could explain why this is happening I'd appreciate it too.
-thanks in advance pyromonki
Re: Transferring Structure variables?(simple problem)
Quote:
Originally Posted by
pyromonki
The book doesn't explain templates very well either,....
Which Book?
Have you been diligent in reading EVERY word, TYPING in EVERY piece or code, then STEPPING through EVERY line with a debugger??
ps: I would have sent this privately, but you did not show the courtesy of properly initializing your profile....
Re: Transferring Structure variables?(simple problem)
I don't know what's wrong with my profile.
But the book is "Data Structures using c++".
http://www.amazon.com/Data-Structure.../dp/0619159073
I don't like the book at all, it'll go over the basic concepts of the principle say link listing. And then kinda take it to a new level without explaining much. And it's flat out frustrating.
The internet has taught me more than the book has. :(
Edit: While I've read the book, I can't say I've typed everything in. The examples they give are self-explanatory. It's the programming exercises that throw me for a loop. :/
and why won't this .exe build? I'm going crazy. Am I not allowed to use a struct variable type from the header? O_o
and why is using binaryTreeType<int> test to define a class object (which is the only way) a problem?
and also once again, I appreciate any help.
Re: Transferring Structure variables?(simple problem)
Quote:
The book doesn't explain templates very well either, ...
so please excuse my ignorance, I'm trying my best to understand template classes.
No problem, just find another book about templates that suit you well. :)
Quote:
I don't like the book at all, it'll go over the basic concepts of the principle say link listing. And then kinda take it to a new level without explaining much. And it's flat out frustrating.
This is, dare say, typical situation for self education, so you have no reason to get frustrated. Just keep searching the books that really help you move on. And be prepared to the fact that the number of the books will be kinda scaring (in case you intend to move really far from begin) :D
Re: Transferring Structure variables?(simple problem)
Quote:
Originally Posted by
pyromonki
I don't know what's wrong with my profile.
Yet you still do not have private messageing enabled as a simple example....
Quote:
Edit: While I've read the book, I can't say I've typed everything in. The examples they give are self-explanatory. It's the programming exercises that throw me for a loop.
This is the root cause of most people problems when trying to learn. They THINK they have read and understood, but unless you actually DO IT, this is usually a falacy.
If I were to quote a paragraph from the book, I would bet significant money, that you could NOT tell me EXACTLY what was covered in the immediately preceeding and subsequent paragraphs (without opening the book).
BUT if you were to type in every single sample piece of code, and step through every line with a debugger, watching all of the variables as each step executes, then I am willing to bet that you will remember what the program does if presented with it again.
For a beginner, the following should provide at least a good hour of study...
Code:
include <iostream>
using namespace std;
int p(int *p, int v)
{
if (v == *p++)
return *p;
else
return v;
}
int main()
{
int a[]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}
int *p = a;
int v = 1;
for (int i=0; i<=10;++i)
{
v = f(p, v);
cout << v << end;
}
Re: Transferring Structure variables?(simple problem)
^I'm gonna assume that you meant to put int f instead of p for the function name right?
and wouldn't that program display the same thing ten times?
There's nothing telling it to go through the array, you just have a pointer pointing to it.
when you put p into the function f shouldn't it be p[i]?
if you don't have anything telling the array to increase the results just gonna be the same every time.
and also.. the syntax. :(
I came on this forum to learn how this template class works. I did the main test function by myself along with the implementation file. I just don't understand why it's not building an .exe.
Re: Transferring Structure variables?(simple problem)
It's also a good example of code designed to teach a concept which no decent coder would actually write in practice.
And I think you meant to call the function f, not p.
Re: Transferring Structure variables?(simple problem)
Quote:
Originally Posted by
pyromonki
I just don't understand why it's not building an .exe.
The linker is failing. Where is the function nodeCount actually *defined*? As in, where is the code that it will execute?
Re: Transferring Structure variables?(simple problem)
Yes, the post was timed in raw..and the function should have definately been "int f(....)"...The main intended issue was the local manipulation of the pointer.
As far as the template specific issue...What I always recommend is to do the following (for beginners, and even intermediate programmers.
1) Create a typedef "T" which represents a (real) class that is a potential target for template specialization.
2) Write a (non-template) version of the code that uses "T" in all appropriate places.
3) Throughly test this code. (it is easier to test non-template code, even for compiler errors)
4) MAKE A COPY OF THIS CODE - and save it.
5) Remove the typedef and make it a "<template typename T>" class.
6) Verify that it continues to pass your tests
7) IF you run into problems with specialization for a different type, go back to step #3 with a typedef of the specialization that is giving problems.
99% of the time when this approach is taken, the problem "solves itself" (and often reveals something really silly..)
I will resort to this technique even after a decade of developing template based code ifg I run into problems.....
Re: Transferring Structure variables?(simple problem)
here it is in all it's shame.
PHP Code:
#include<iostream>
#include"tree.h"
using namespace std;
template<class elemType>
bool binaryTreeType<elemType>::isEmpty()
{
return(root==NULL);
}
template<class elemType>
binaryTreeType<elemType>::binaryTreeType()
{
root =NULL;
}
template<class elemType>
void binaryTreeType<elemType>::inorderTraversal()
{
inorder(root);
}
template<class elemType>
void binaryTreeType<elemType>::preorderTraversal()
{
preorder(root);
}
template<class elemType>
void binaryTreeType<elemType>::postorderTraversal()
{
postorder(root);
}
template<class elemType>
int binaryTreeType<elemType>::treeHeight()
{
return height(root);
}
template<class elemType>
int binaryTreeType<elemType>::treeNodeCount()
{
return nodeCount(root);
}
template<class elemType>
int binaryTreeType<elemType>::treeLeavesCount()
{
return leavesCount(root);
}
template<class elemType>
void binaryTreeType<elemType>::inorder(nodeType<elemType> *p)
{
if(p !=NULL)
{
inorder(p->llink);
cout<<p-=>info<<" ";
inorder(p->rlink);
}
}
template<class elemType>
void binaryTreeType<elemType>::preorder(nodeType<elemType> *p)
{
if (p !=NULL)
{
cout<<p->info<<" ";
preorder(p->llink);
preorder(p->rlink);
}
}
template<class elemType>
void binaryTreeType<elemType>::postorder(nodeType<elemType> *p)
{
if (p !=NULL)
{
postorder(p->llink);
postorder(p->rlink);
cout<<p->info<<" ";
}
}
template<class elemType>
int binaryTreeType<elemType>::height(nodeType<elemType> *p)
{
if (p==NULL)
return 0;
else
return 1 + max(height(p->llink),height(p->rlink));
}
template<class elemType>
int binaryTreeType<elemType>::max(int x, int y)
{
if (x>=y)
return x;
else
return y;
}
template<class elemType>
int binaryTreeType<elemType>:: nodeCount(nodeType<elemType> *p) //right here
{
if (p==NULL)
return 0;
else{
int count=1;
count+=nodeCount(p->llink);
count+=nodeCount(p->rlink);
return count;
}
}
template<class elemType>
int binaryTreeType<elemType>::leavesCount(nodeType<elemType> *p)
{
if (p->llink==NULL && p->rlink==NULL)
return 1;
else
return leavesCount(p->llink)+leavesCount(p->rlink);
}
template<class elemType>
void binaryTreeType<elemType>::copyTree(nodeType<elemType>* &copiedTreeRoot, nodeType<elemType>* otherTreeRoot)
{
if (otherTreeRoot ==NULL)
copiedTreeRoot =NULL;
else
{
copiedTreeRoot=new nodeType<elemType>;
copiedTreeRoot->info = otherTreeRoot->info;
copyTree(copiedTreeRoot->llink, otherTreeRoot->llink);
copyTree(copiedTreeRoot->rlink, otherTreeRoot->rlink);
}
}
template<class elemType>
void binaryTreeType<elemType>::destroy(nodeType<elemType>* &p)
{
if (p !=NULL)
{
destroy(p->llink);
destroy(p->rlink);
delete p;
p=NULL;
}
}
template<class elemType>
binaryTreeType<elemType>::binaryTreeType(const binaryTreeType<elemType>& otherTree)
{
if (otherTree.root==NULL)
root=NULL;
else
copyTree(root, otherTree.root);
}
template<class elemType>
binaryTreeType<elemType>::~binaryTreeType()
{
destroy(root);
}
template<class elemType>
const binaryTreeType<elemType>& binaryTreeType<elemType>::operator=(const binaryTreeType<elemType>& otherTree)
{
if (this != &otherTree)
{
if (root != NULL)
destroy(root);
if (otherTree.root ==NULL)
root=NULL;
else
copyTree(root, otherTree.root);
}
return *this;
}
Do you see the problem? if you do, could you explain it?
(I already moved nodeCount() to public.
The class originally wanted me to use treeNodeCount()
but gave me no way to use root. so in the test program I used my own variables.
thanks in advance.
Re: Transferring Structure variables?(simple problem)
I take it that's tree.cpp?
Try adding
Code:
#include "tree.cpp"
to the very end of tree.h. Normally this would *not* be the way to go---you'd just compile tree.cpp alongside your own source file so the linker has access to both---but templates are a bit odd in that the definitions must be accessible to every translation unit (source file), so doing the above usually works.