Inherited getter , not returning correct value? virtual functions

At the moment I have a situation like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class foo {
    public:
        int type;
        virtual int getType(){ return type; }
        foo() { type = 1; }
};

class bar : public foo {
    public:
        bar() { type = 2; }
};

main () {
   bar *b = new bar();
   b->getType(); /* This returns 1 instead of 2 ?? */

}


any ideas on what is going wrong??
Okay... I ran this:

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 foo
{
    public:
        int type;
        int getType()
		{
			return type;
		}
        foo()
		{
			type = 1;
		}
};

class bar : public foo
{
    public:
        bar()
		{
			type = 2;
		}
};

int main ()
{
   bar *b = new bar();
   cout<<b->getType();
}


And it worked perfectly!

- Kyle
b->getType(); /* This returns 1 instead of 2 ?? */
How can you know that it returns 1 when you don't print the value?
Even if function getType was not declared as virtual in any case it shall return 2 because constructor of bar overwrites the value of data member type set before by constructor foo to 1.
Last edited on
Peter87:
I was simplifying the code, the real code is part of a compiler project I'm working on, and I thought it would probably be too large to paste here.

and looks like this:

1
2
3
4
5
6
7
8
9
10
11
NVariableDeclaration::NVariableDeclaration(NIdentifier* id, int type) {
           this->type = type;
           name = id->getID();
           delete(id);
           nodeType = VARDEC;
           cout << typemap_get(type) << endl;
          cout << typemap_get(this->type) << endl;
          cout << typemap_get(this->getType()) << endl;
          cout << typemap_get(this->resolveType()) << endl;
 }


Where the first two output the correct type and the second two output the type which would be set in the base classes constructor.

Kyle:
I'd need to be able to override the getType() function, as for some nodes that derive from the base class can't have their types computed instantaneously IE a binary operator node doesn't know its type until it evaluates the types of its children.
whereas the type of a variable declaration node is known instantaneously.

Last edited on
Simplifying the code is fine, even recommended, as long as the simplified code still has the problem that you want to show.

It's impossible to know what the problem is by just seeing the code of the NVariableDeclaration constructor. There are so much code missing that we don't know about.
Ok Here is the offending code:
Ignore the comments and the line numbers..

Node.hpp
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
  1 #ifndef _NODE_HPP_
  2 #define _NODE_HPP_
  3
  4 #include <iostream>
  5 #include <deque>
  6 #include <string>
  7 #include "../Errors/SemanticErrors.hpp"
  8 #include "../SymbolTable/SymbolTable.hpp"
  9
 10 using namespace std;
 11
 12
 13 /*
 14 typedef vector<NStatement *> StatementList;
 15 May not end up using these*//*
 16 typedef vector<NExpression *> ExpressionList;
 17 typedef vector<NVariableDeclaration *> ViarableList;
 18 */
 19
 20 class Node;
 21 typedef deque<Node *> node_children_t;
 22
 23 class SymbolTable;
 24 /* Top level Base Class */
 25 class Node {
 26 public: /* This should be changed to private at some point. */
 27         SymbolTable* table;
 28         int nodeType;
 29         int type;
 30         virtual int resolveType();
 31
 32         node_children_t children; /* This shouldn't be publicly exposed. Fix! */
 33         string name; /* Same here... */
 34         Node();
 35         Node(Node*);
 36         virtual ~Node();
 37         virtual int print() const;
 38         virtual int getType() const;
 39         virtual string getID();
 40         node_children_t getChildren() const;
 41         virtual int check();
 42         virtual int addTable(SymbolTable*);
 43         virtual int getNodeType();
 44 };
 45
 46 #endif 


Node.cpp
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
  1 #include "Node.hpp"
  2 #include "TypeDefs.hpp"
  3
  4 #define UNDEFINED -1
  5
  6 Node::Node() {
  7         name = "Node";
  8         type = INVALIDTYPE;
  9 }
 10
 11 Node::Node(Node *child) {
 12         children.push_back(child);
 13         name = "Node";
 14         type = INVALIDTYPE;
 15 }
 16
 17 Node::~Node() {
 18
 19 }
 20
 21 int Node::print() const {
 22         cout << name << endl;
 23         return 1;
 24 }
 25
 26 node_children_t Node::getChildren() const {
 27         return children;
 28 }
 29
 30 int Node::getType() const {
 31         return this->type;
 32 }
 33
 34 int Node::resolveType() {
 35         return type;
 36 }
 37
 38 string Node::getID() {
 39         return name;
 40 }
 41
 42 int Node::check() {
 43         int isValid = 1;
 44         node_children_t::iterator it;
 45
 46         for(it = children.begin(); it != children.end(); ++it) {
 47                 isValid = (*it)->check();
 48         }
 49
 50         return isValid;
 51 }
 52
 53 int Node::addTable(SymbolTable* table) {
 54         if(table == NULL) {
 55                 return 0;
 56         }
 57         else {
 58                 this->table = table;
 59                 return 1;
 60         }
 61 }
 62 int Node::getNodeType() {
 63         return nodeType;
 64 }


NVariableDeclaration.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  1 #ifndef _NVARIABLEDECLARATION_HPP_
  2 #define _NVARIABLEDECLARATION_HPP_
  3
  4 #include "Node.hpp"
  5 #include "NIdentifier.hpp"
  6 #include <string>
  7
  8 class NVariableDeclaration : public Node {
  9 private:
 10         int type;
 11 public:
 12         /* args are identifier & type */
 13         NVariableDeclaration(NIdentifier*, int);
 14         /* args are identifier, bit expression, type - arrays */
 15         NVariableDeclaration(NIdentifier*, int, Node*);
 16         string getID() const { return name;}
 17         virtual int check();
 18 };
 19
 20 #endif 


NVariableDeclaration.cpp
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
32
33
34
35
36
37
 #include "NVariableDeclaration.hpp"
  2 #include "TypeDefs.hpp"
  3 #include "../Errors/TypeMap.hpp"
  4 NVariableDeclaration::NVariableDeclaration(NIdentifier* id, int type) {
  5         this->type = type;
  6         name = id->getID();
  7         delete(id);
  8         nodeType = VARDEC;
  9         cout << typemap_get(type) << endl;
 10         cout << typemap_get(this->type) << endl;
 11         cout << typemap_get(this->getType()) << endl;
 12         cout << typemap_get(this->resolveType()) << endl;
 13 }
 14
 15 NVariableDeclaration::NVariableDeclaration(NIdentifier* id, int type, Node *block) {
 16         this->type = type;
 17         children.push_back(block);
 18         name = id->getID();
 19         delete(id);
 20         nodeType = VARDEC;
 21         cout << typemap_get(type);
 22 }
 23
 24 int NVariableDeclaration::check() {
 25         int isValid = 1;
 26         /*THIS CHECK IS ALREADY PERFORMED IN THE SYMTABLE GENERATOR*/
 27         /* Does the variable name already exist in current scope? */
 28 /*      if(table->lookupCurrentScope(name) != NULL) {
 29                 error_var_exists(name);
 30                 isValid = 0;
 31         }
 32 */
 33         /* If we have children (i.e. array access bit expressions), check them. */
 34         isValid &= Node::check();
 35
 36         return isValid;
 37 }





The essence of the idea is still the same as the first example I posted.

getType and resolveType() (are basically identical at the moment), seem to return a value which is created by the default node constructor even when something like this is called:

 
NVariableDeclaration* varDec = new NVariableDeclaration(new Node(id) , 15);


The constructor of varDec prints out, 15 for the first two cases, IE acessing type directly, but 1 for the other two cases, IE the value that is given by the default node constructor.
Oh, i think I spotted it. it is probably line 9-10 in NVariableDeclaration.hpp
Topic archived. No new replies allowed.