class foo {
public:
int type;
virtualint 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 ?? */
}
#include <iostream>
usingnamespace 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();
}
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.
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.
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.
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.
#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.