:: Cannot do heritage in c++

Hi, i'm start learning c++ in my colleage, and i'm having a problem that i cannot resolve. The heritage does't seem to work, when i compile it appears base class undefined.
My code is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef CIDADE_H
#define CIDADE_H

#include "Lugar.h"
#include <iostream>
#include <string>

using namespace std;

class Cidade: public Lugar{

private:
	int pontos;
public:
	Cidade(string, int);
};

Cidade::Cidade(string a,int pontosX):Lugar(a){
		pontos=pontosX;
}

#endif 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifndef LUGAR_H
#define LUGAR_H
#include "Utilizador.h"
#include <iostream>
#include <string>

using namespace std;

class Lugar{
	private:
		string nome;
		Lugar* *Utilizador;
	public:
		Lugar(string);
};
Lugar::Lugar(string nomeX){
	nome=nomeX;
}
#endif 


Thanks in advance
You've messed up the constructor of the child class. A constructor doesn't extend anything. A class does.

For the constructor of the child class, move the constructor of the base class INSIDE the constructor, rather than placing it in its 'name':

1
2
3
4
Cidade::Cidade(string a,int pontosX) {
 	Lugar(a); // I'm not sure this is the correct way in C++. You might have to use "*this = Lugar(a)".
	pontos=pontosX;
}
closed account (DSLq5Di1)
@Gaminic
That is an initialization list calling the base constructor, which is perfectly fine.

@zumbicap
I've no problems compiling here -> http://ideone.com/mDjYn. Could you provide the code that results in your error?
I'm using Visual Studio, and i don't know if the problem is here. I'm gonna post the all code:
Thanks for tour replies.

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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#ifndef LUGAR_H
#define LUGAR_H
#include <iostream>
#include <string>

using namespace std;

#include "Utilizador.h"

class Lugar{
	private:
		string nome;
		Utilizador* *arr;
		int tam;
		int posicao;
	public:
		Lugar(string);
		string getNome();
		void setNome(string);
		~Lugar();
		virtual void escrever(ostream&);
		Lugar& operator=(const Lugar&);
		bool operator==(const Lugar&);
		//bool operator>(const Lugar&); nao faz sentido comparar lugares
		//bool operator<(const Lugar&);
		void setUtilizador(Utilizador*);
};

/////////////////////////////////CONSTRUCTOR///////////////////////////////////

Lugar::Lugar(string nomeX){
	nome=nomeX;
	posicao=0;
	tam=50;
	arr = new Utilizador*[tam];
}

/////////////////////////////////METHODS///////////////////////////////////

void Lugar::escrever(ostream& out){
 cout<<"Nome: "<<nome<<endl;
}

/////////////////////////////////GET & SET///////////////////////////////////

void Lugar::setUtilizador(Utilizador* util){
	if (tam>=posicao){
	tam+=50;
	Utilizador* *temp = new Utilizador*[tam];
	for (int i=0;i<posicao;i++){
		temp[i]=arr[i];
		}
	delete[] arr;
	arr=temp;
	delete[]temp;
	}
	arr[posicao]=util;
	posicao++;
}

string Lugar::getNome(){
return nome;
}

void Lugar::setNome(string nomeX){
this->nome=nomeX;
}

/////////////////////////////////DESTRUCTOR///////////////////////////////////

Lugar::~Lugar(){
}

/////////////////////////////////OPERATORS///////////////////////////////////

Lugar& Lugar::operator=(const Lugar& a){
	if(this!=&a){
	nome=a.nome;
	}
	return *this;
}

bool Lugar::operator==(const Lugar& a){
	if(this!=&a){
	return false;
	}
	else return true;
}


/////////////////////////////////OSTREAM///////////////////////////////////

ostream& operator<<(ostream&out, Lugar& a){
	a.escrever(out);
	return out;
}

#endif 


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
#ifndef _Utilizador_
#define _Utilizador_

#include <iostream>
#include <string>
using namespace std;

#include "Cidade.h"


class Utilizador{

private:

	string nick;
	string mail;
	Utilizador* *amigos;
	Cidade* *cidades_check;
	int npontos;

	int dim_amigos;
	int ind_amigos;
	int dim_cidades_check;
	int ind_cidades_check;

public:

	Utilizador(string,string);
	void setNick(string);
	void setMail(string);
	string getNick();
	string getMail();
	void setAmigos(Utilizador []);
	void setCidades_check(Cidade * []);
	Utilizador* getAmigos(Utilizador * []);
	Cidade * getCidade(Cidade * []);
	void setNPontos(int);
	int getNPontos();
};

Utilizador::Utilizador(string nick_, string mail_){

	nick=nick_;
	mail=mail_;
	npontos=0;

	//Dimensões e indices dos arrays dinâmicos
	dim_amigos=50;
	dim_cidades_check=50;
	ind_amigos=0;
	ind_cidades_check=0;

	//declaração arrays dinâmicos
	amigos= new Utilizador * [dim_amigos];
	cidades_check = new Cidade * [dim_cidades_check];
}

#endif 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef TESTE_H
#define TESTE_H
#include <iostream>
#include <string>

using namespace std;

#include "Lugar.h"
#include "Cidade.h"
#include "Utilizador.h"
#include "Ler.h"

int main(){
	Lugar l1=Lugar("povoa");
	Lugar l2=Cidade("Porto",5);
	r.addLugar(l1);

	
return 0;
};
#endif 



ERROR:

c:\users\bruno\documents\my dropbox\esinf-local\rede_social2\rede_social2\cidade.h(11): error C2504: 'Lugar' : base class undefined
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#ifndef CIDADE_H
#define CIDADE_H

#include <iostream>
#include <string>

using namespace std;
#include "Lugar.h"
#include "Utilizador.h"

class Cidade: public Lugar{

private:
	int pontos;
	Utilizador* mayor;
public:
	Cidade(string, int);
	~Cidade();
	void escrever(ostream&);
	Cidade& operator=(const Cidade&);
	bool operator==(const Cidade&);
	bool operator>(const Cidade&);
	bool operator<(const Cidade&);
	int getPontos();
	int setPontos(int);
	string getNome();
	void setNome(string);
	void setMayor(Utilizador*);
};

/////////////////////////////////CONSTRUCTOR///////////////////////////////////

Cidade::Cidade(string a,int pontosX):Lugar(a){
		pontos=pontosX;
}

/////////////////////////////////METHODS///////////////////////////////////
	
void Cidade::escrever(ostream& out){
	Cidade::escrever(out);
 cout<<" Pontos: "<<pontos<<endl;
}

/////////////////////////////////GET & SET///////////////////////////////////
void setMayor(Utilizador* ut){
	if (ut>mayor || mayor==null){
	mayor=ut;
	}
}

int Cidade::getPontos(){
	return this->pontos;
}

int Cidade::setPontos(int a){
	pontos=a; // este pontos nao sao do utilizador mas da cidade (actualizar os pontos)
}	

string Cidade::getNome(){
	Lugar::getNome;
}

void Cidade::setNome(string a){
	Lugar::setNome(a);
}

/////////////////////////////////DESTRUCTOR///////////////////////////////////

Cidade::~Cidade(){
}

///////////////////////////////OPERATORS///////////////////////////////

Cidade& Cidade::operator=(const Cidade& a){
	if(this!=&a){
	Lugar::operator=(a);
	pontos=a.pontos;
	}
	return *this;
}

bool Cidade::operator==(const Cidade& a){
	if(this!=&a){
		if (pontos==a.pontos){
			return true;}
		else return true;
	}
}

bool Cidade::operator>(const Cidade& a){
	if(this!=&a){
		if (pontos>a.pontos){
			return true;}
		else return true;
	}
}


bool Cidade::operator<(const Cidade& a){
	if(this!=&a){
		if (pontos<a.pontos){
			return true;}
		else return true;
	}
}


/////////////////////////////////OSTREAM///////////////////////////////////

ostream& operator<<(ostream&out, Cidade& a){
	a.escrever(out);
	return out;
}

#endif 


sorry I missed this one.

Do you think it's the visual studio? I tried to re-install it and nothing.
I have to deliver this academic work and my teacher says that he don't understand why this is happening.

Thank you for the time of everyone that replies.
http://www.cplusplus.com/forum/articles/10627/ (section 4 and next)
main includes Lugar, that includes Utilizador, that includes Cidade, that includes Lugar. But LUGAR_H is already defined so the entire header is skiped.
So when it tries to compile class Cidade, still doesn't know what is class Lugar so it fails.

Later you may have redefinition, so you better separate implementation from definition (or make them inline, see the article for how to).

1
2
3
4
5
6
7
8
9
10
void Lugar::setUtilizador(Utilizador* util){
//...
	Utilizador* *temp = new Utilizador*[tam];
//...
	delete[] arr;
	arr=temp;
	delete[]temp; //¿?
//...
	arr[posicao]=util; //invalid memory access
}
You better use std::vector

Oh, getters and setters are evil http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html
Oh, getters and setters are evil http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html


Previously I was reading up on Java Spring framework and they have setter injection concept. They relies heavily on JavaBeans notation so during run-time, the Spring Container know how to invoke the setter method successfully.

E.g
<bean id="myDao" class="com.test.MyDAO">
<property name="dataSource" ref="dataSource"/>
<property name="sqlTemplate" ref="sqlSessionFactory"/>
</bean>

Above configure property name dataSource and sqlTemplate. So how does Spring Container know how to invoke them and passed in the parameters as declared ?

Concept is simple. They uses JavaBeans notation and all our classes just need to define a setter method.

E.g
class MyDAO {
public void setDataSource(...);
public void setSqlTemplate(...);
}

Spring will infer from the property name and then call the relevant method set<PropertyName> automatically.

So this is a classic example on why setter/getter is needed for some Java framework. Idea is simple and it works. Rather than writing off getter/setters are evil, I would prefer to say keep your options open. You never know when you need it cuz some Java framework require this too.

Likewise, the concept applies to C++. If one day, certain C++ framework decide to adopt the JavaBeans notation, then the C++ class setter/getter is mandatory indeed.

My knowledge about java beans is zero, so please be patient and correct me.
The issue is addressed in page 4. I want to recall this: "You aren't supposed to call these methods yourself. They exist for an automated tool to use."

I (maybe) can live with public function that aren't supposed to be called. But I'd rather make my variables public than write 6 lines of code for each of them that will "do nothing" ("an alternative" http://www.cplusplus.com/forum/articles/36872/#msg200792 )
(this will be a good use for friends)

You should check if private @property int property; is valid now.
Last edited on
Thanks a lot guys. This includes are still odd, but now it's working. Thanks
Topic archived. No new replies allowed.