Virtual fuctions

okay im trying to make a sort of data base, i dont really need it to store the data permanently, rather just in memory for the time being..
so i thought that what i needed were objects that would be able to link in a link list with each other and hold different data types... i wanted to use a virtual function in a parent class that all others would implement in their own way, but when i try to use vurtual functions my code implodes.. any way i guess i should post the code...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//MushData.h
//this class isnt meant to be used,
//other classes that will be used inherate from it
#ifndef _MUSHDATA_H
#define _MUSHDATA_H
namespace MushBase{
    class MushData{
        public:
        MushData* prev;
        MushData* next;
        //pub vars
        MushData();//no args
        MushData(MushData* p,MushData* n);//pointers for prev and next
        virtual void setData();
    };
}
#endif//_MUSHDATA_H 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//MushData.cpp
#include "MushData.h"
namespace MushBase{
    MushData::MushData(){
        prev=0;
        next=0;
    }
    MushData::MushData(MushData* p,MushData* n){
        prev=p;
        next=n;
    }
    MushData::setData(){
        //do nothing
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//MushString.h
#ifndef _MUSHSTRING_H
#define _MUSHSTRING_H
#include "MushData.h"
namespace MushBase{
    class MushString:public MushData{
        //class inherates from MushData, the pointers
        //next and prev are implied.
        public:
        char str[256];
        MushString();
        MushString(char* s);
        MushString(char* s, MushData* p,MushData* n);
        void setData(char* s);
    };
}
#endif//_MUSHSTRING_H 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//MushString.cpp
#include "MushString.h"
#include <iostream>
namespace MushBase{
    MushString::MushString(){
        str[0]=0;
    }
    MushString::MushString(char* s){
        std::cout<<s;
    }
    MushString::MushString(char* s,MushData* p, MushData* n){
    }
    void MushString::setData(char* s){
        std::cout<<s;
    }
}

and in the main file i have
1
2
3
4
5
6
7
8
9
//main.cpp
#include <iostream>
#include "MushString.h"
int main(){
    MushBase::MushData* root;
    root = new MushBase::MushString;
    char str[] ="test";
    root->setData(str);
}


im useing the code blocks IDE, dunno if that helps, there are prolly some holes in my code i know this is the first project ive ever worked on...

and just incase you are wondering im just diong it to see if i can, and to practic and get better :P
oh i almost forgot the errors:
C:\Users\Mushroom\Documents\iunno\DataBase\main.cpp||In function `int main()':|
C:\Users\Mushroom\Documents\iunno\DataBase\main.cpp|8|error: no matching function for call to `MushBase::MushData::setData(char[5])'|
C:\Users\Mushroom\Documents\iunno\DataBase\MushData.h|14|note: candidates are: virtual void MushBase::MushData::setData()|
||=== Build finished: 1 errors, 0 warnings ===|
Last edited on
In MushData, function is 'void setData()' whereas in MushString function is 'void setData(char*)'
In C++ two functions with the same name, but different parameters are considered different.
Add a 'char*' parameter to 'virtual void MushBase::MushData::setData()'
The prototype of the setData() and the definition don't match:

1
2
3
4
5
6
7
8
9
10
11
12
//MushData.h
//this class isnt meant to be used,
//other classes that will be used inherate from it
#ifndef _MUSHDATA_H
#define _MUSHDATA_H
namespace MushBase{
    class MushData{
        ...
        virtual void setData();
    };
}
#endif//_MUSHDATA_H  



1
2
3
4
5
6
7
8
//MushData.cpp
#include "MushData.h"
namespace MushBase{
   ...
    MushData::setData(){ //you should write void MushData::setData() {};
        //do nothing
    }
}


But if the setData of base class does nothing you can use pure virtual funcion:

virtual void setData() = 0;
Last edited on
whats a "pure" virtual function, and no i dont plan on using the MushData class for anything other than to make all the other ones line up in a linked list...
how can i make it so that i can set the data, when i may not know how future children classes will need to be set...
Last edited on
Pure virtual function is a function of a base class which don't contain any instructions. It only make an appeal that in the derived classes have to be made one.

http://en.wikipedia.org/wiki/Virtual_function

@hamsterman:
In my opinion the arguments may be different between function of base class and derived classes.

Here is my probe code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
using namespace std;

class base
{
	virtual void fnc();
};
void base::fnc(){}

class derived:base
{
	void fnc (int i){cout << "derived " << i << endl;}
};


int main()
{

	return 0;
}


if I use the pure virual function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;

class base
{
	virtual void fnc() = 0;
};

class derived:base
{
	void fnc (int i){cout << "derived " << i << endl;}
};


int main()
{

	return 0;
}
your code wont compile for me...
I tried two compiler and I could compile properly. I used bcc32 v 5.5 on Windows and g++ on Ubuntu.
What kind of compiler do you use?
i use code::blocks, http://www.codeblocks.org/
it was recomended by some tutorial long ago, i like it because its simple, tho i'd switch to one thats better as long as it isnt to fancy and compicated...
I tried the codebloks and it works for me that code. 8.02 version
The codelite comes frequently.
http://www.codelite.org/
Last edited on
i downloaded Dev-c++ and it worked fine in it... i guess i'll start useing it now...
well actually it wont let me:
1
2
base* test;
    test = new derived;
Last edited on
Sorry, hamsterman was right.

It seems my code is compiled propery but if you want to use it than it was a problem. Here is the good code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
using namespace std;

class base
{
	public:
	virtual void fnc();
};
void base::fnc(){cout << "base " << endl;}

class derived:base
{
	public:
	void fnc (){cout << "derived " << endl;}
};


int main()
{
	base * test1 = new base;
	base * test2 = (base*)new derived;
	test1->fnc();
	test2->fnc();
	return 0;
}


I think that you should take out the setData function from your base class. The specializated setData function belong to only the derived classes in my opinion:

class MushBase
{
};

class MushString: public MushBase
{
void setData(char *s);
};

class MushBeer: public MushBase
{
void setData(int amount);
};

Sorry again.
well if i take it from my base class, then how can i access the function when useing a pointer of the base type to point to the darived type?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
using namespace std;

class base{
      //just to make a Linked List possible
};

class derived : public base{
      public:
      int i;
      int getIt(int j);
};
int derived::getIt(int j){
    return i+j;
}

int main(){
    //i need results like:
    derived var;
    var.i=5;
    cout<<var.getIt(3);
    // that, but it needs to work from a pointer like
    base* var2;
    var2 = new derived;
    //var2->i=5;
    //var2->getIt(4);
    //^ wont work
    cin.get();
}

There is no point in having a base class with no member functions or data members...you would have to define getIt() as a virtual function inside the base class.
Are you trying to make a linked list? Because linked lists are typically made like this:
1
2
3
4
5
6
7
8
9
10
template <typename T>
class node{
    T data;
    node *next;
};

template <typename T>
class list{
    node<T> *first;
};
thanl you helios, i didnt even think of useing a template!
i can use that data to store pointers as well? i need a way to store strings so if i cant store a pointer than im kinda back at square one :(
ok, you can store the address of derived classes with the help of pointer of base class, but if you want to use the function of a derived class you should convert that pointer to pointer of derived class.

1
2
3
4
5
6
7
8
9
10
base* var2;
    var2 = new derived;
    //var2->i=5;
    //var2->getIt(4);
    //^ wont work

   // just make a pointer of derived class
   derived * tmp = (derived *)var2;
   // and you can use the specialized functions
   tmp->getIt(4);


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
using namespace std;

class base
{
	public:
	virtual void fnc();
	base *next;
};
void base::fnc(){cout << "base " << endl;}

class derived:base
{
	public:
	void fnc (){cout << "derived " << endl;}
	void fnc (int i){cout << "derived " << i << endl;}
	
};


int main()
{
	base * test1 = new base;
	base * test2 = (base*)new derived();
	test1->fnc();
	test2->fnc();
	derived *tmp = (derived *)test2;
	tmp->fnc(4);
	return 0;
}


The output:
base
derived
derived 4


It is good for that you want to store different classes which is derived from a base class. Then you can make a list which is based on basic class and put into your different classes into the list. But if you want to use them, then you have to convert to the suitable class.

http://www.cplusplus.com/doc/tutorial/typecasting/
look the dynamic_cast
Last edited on
Topic archived. No new replies allowed.