derivation is confusing. Need help.

So basically this program is from an exercise but even though I did everything I thought I was supposed to it still doesn't work.

ERRORS:
error LNK2019: unresolved external symbol "public: virtual __thiscall...
abstr_emp::~employee(void)"
error LNK2001: unresolved external... ~abstr_emp(void)
error LNK1120: 1 unresolved external

Everything with the program should work so it must be in the source code. I suspect it has something to do with destructors and constructor. (not a wild guess since half the program is just constructors)

emp.h
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
#include <iostream>
#include <string>

class abstr_emp
{
private:
	std::string fname; // first name
	std::string lname; // last name
	std::string job;
public:
	abstr_emp();
	abstr_emp(const std::string & fn, const std::string & ln,
		const std::string & j);
	virtual void ShowAll() const; // labels and shows all data
	virtual void SetAll(); // prompts user for values
	friend std::ostream &
		operator<<(std::ostream & os, const abstr_emp & e);
	// just displayes first and last name
	virtual ~abstr_emp() = 0;
};

class employee : public abstr_emp
{
public:
	employee();
	employee(const std::string & fn, const std::string & ln,
		const std::string & j);
	virtual void ShowAll() const;
	virtual void SetAll();
};

class manager : virtual public abstr_emp
{
private:
	int inchargeof; // number of abstr_emps managed
protected:
	int InChargeOf() const { return inchargeof; } // output
	int & InChargeOf() { return inchargeof; } // input
public:
	manager();
	manager(const std::string & fn, const std::string & ln,
		const std::string & j, int ico = 0);
	manager(const abstr_emp & e, int ico);
	manager(const manager & m);
	virtual void ShowAll() const;
	virtual void SetAll();
};

class fink : virtual public abstr_emp
{
private:
	std::string reportsto;
protected:
	const std::string ReportsTo() const { return reportsto; }
	std::string & ReportsTo() { return reportsto; }
public:
	fink();
	fink(const std::string & fn, const std::string & ln,
		const std::string & j, const std::string & rpo);
	fink(const abstr_emp & e, const std::string & rpo);
	fink(const fink & e);
	virtual void ShowAll() const;
	virtual void SetAll();
};

class highfink: public manager, public fink // management fink
{
public:
	highfink();
	highfink(const std::string & fn, const std::string & ln,
		const std::string & j, const std::string & rpo,
		int ico);
	highfink(const abstr_emp & e, const std::string & rpo, int ico);
	highfink(const fink & f, int ico);
	highfink(const manager & m, const std::string & rpo);
	highfink(const highfink & h);
	virtual void ShowAll() const;
	virtual void SetAll();
};


emp.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
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include "stdafx.h"
#include <iostream>
#include "emp.h"

abstr_emp::abstr_emp()
{
	fname = "no fname";
	lname = "no lname";
	job = "no job";
}

abstr_emp::abstr_emp(const std::string & fn, const std::string & ln,
		const std::string & j)
{
	fname = fn;
	lname = ln;
	job = j;
}

void abstr_emp::ShowAll() const
{
	std::cout << "First name: " << fname << std::endl;
	std::cout << "Last name: " << lname << std::endl;
	std::cout << "Job: " << job << std::endl;
}

void abstr_emp::SetAll()
{
	std::cout << "Fname: ";
	std::cin >> fname;
	std::cout << "Lname: ";
	std::cin >> lname;
	std::cout << "Job: ";
	std::cin >> job;
}

std::ostream & operator<<(std::ostream & os, const abstr_emp & e)
{
	os << e.fname << e.lname;
	return os;
}

employee::employee() : abstr_emp("no fname", "no lname", "employee")
{ }

employee::employee(const std::string & fn, const std::string & ln,
		const std::string & j) : abstr_emp(fn, ln, j)
{ }

void employee::ShowAll() const 
{ abstr_emp::ShowAll(); }

void employee::SetAll() 
{ abstr_emp::SetAll(); }

manager::manager() : abstr_emp()
{
	inchargeof = 0;
}

manager::manager(const std::string & fn, const std::string & ln,
				 const std::string & j, int ico) : abstr_emp(fn, ln, j)
{
	inchargeof = ico;
}

manager::manager(const abstr_emp & e, int ico) : abstr_emp(e)
{
	inchargeof = ico;
}

manager::manager(const manager & m)
{
	*this = m;
}

void manager::ShowAll() const
{ 
	abstr_emp::ShowAll(); 
	std::cout << "In charge of " << inchargeof << " people" << std::endl;
}

void manager::SetAll()
{
	abstr_emp::SetAll();
	std::cout << "In charge of: ";
	std::cin >> inchargeof;
}

fink::fink() : abstr_emp()
{
	reportsto = "no one"; 
}

fink::fink(const std::string & fn, const std::string & ln,
		   const std::string & j, const std::string & rpo)
		   : abstr_emp(fn, ln, j) 
{
	reportsto = rpo;
}

fink::fink(const abstr_emp & e, const std::string & rpo)
	: abstr_emp(e)
{
	reportsto = rpo;
}

fink::fink(const fink & e)
{
	*this = e;
}

void fink::ShowAll() const
{
	abstr_emp::ShowAll();
	std::cout << "Reports to: " << reportsto << std::endl;
}

void fink::SetAll()
{
	abstr_emp::SetAll();
	std::cout << "Reports to: ";
	std::cin >> reportsto;
}

highfink::highfink()
{ }

highfink::highfink(const std::string & fn, const std::string & ln,
		const std::string & j, const std::string & rpo,
		int ico) 
		: manager(fn, ln, j, ico), fink(fn, ln, j, rpo), abstr_emp(fn, ln, j)
{ }

highfink::highfink(const abstr_emp & e, const std::string & rpo, int ico)
	: manager(e, ico), fink(e, rpo), abstr_emp(e)
{ }

highfink::highfink(const fink & f, int ico) : fink(f), abstr_emp(f), manager(f, ico)
{ }

highfink::highfink(const manager & m, const std::string & rpo)
	: manager(m), fink(m, rpo), abstr_emp(m)
{ }

highfink::highfink(const highfink & h)
{
	*this = h;
}

void highfink::ShowAll() const
{
	manager::ShowAll();
	std::cout << "Reports to: " << ReportsTo() << std::endl;
}

void highfink::SetAll()
{
	abstr_emp::SetAll();
	manager::SetAll(); // This part may also not work, but probably not
	fink::SetAll();    // the cause of errors
}


main.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
// Ch14_5.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include "emp.h"

using namespace std;

int main(void)
{
	employee em("Trip", "Harris", "Thumper");
	cout << em << endl;
	em.ShowAll();

	manager ma("Amorphia", "Spindragon", "Nuancer", 5);
	cout << ma << endl;
	ma.ShowAll();

	fink fi("Matt", "Oggs", "Oiler", "Juno Barr");
	cout << fi << endl;
	fi.ShowAll();

	highfink hf(ma, "Curly Kew"); // recruitement?
	hf.ShowAll();
	cout << "Press a key for next phase:\n";
	cin.get();
	highfink hf2;
	hf2.SetAll();

	cout << "Using an abstr_emp * pointer:\n";
	abstr_emp * tri[4] = {&em, &fi, &hf, &hf2};
	for (int i = 0; i < 4; i++)
		tri[i]->ShowAll();

	cin.get();

	return 0;
}
Your abstr_empl destructor is pure virtual and is not implemented, but it will be called when any derived class will be destroyed.

Why did you do that?
Last edited on
The header file is all a part of the exercise in my book, the main is also that. I am only supposed to make the emp.ccp file.
You should implement your destructor in cpp file despite fact that it is pure virtual:
abstr_emp::~abstr_emp() {}

Also you will need to implement destructors in all derived classes.
Last edited on
I didn't have to even do that :) My next problem is this:
1
2
3
4
5
6
void highfink::SetAll()
{
	abstr_emp::SetAll();
	manager::SetAll(); // This part may also not work, but probably not
	fink::SetAll();    // the cause of errors
}

I have to enter name multiple times. (3 times, it uses the names entered for the last one) How can I make it so that I only enter name 1 time and the other stuff also 1 time without altering the header file.
Use protected member function of manager and fink to change their private values then call abstr_emp::SetAll. Or, better change manually only one base class private value and call SetAll on other.

This assigment shows exactly how you shouldn't write programs.
What is so bad about it? I think the header file was fine... My code may be a bit messed up though, but I also think my own code was good.
Last edited on
Final version that worked:
1
2
3
4
5
6
7
8
void highfink::SetAll()
{
	abstr_emp::SetAll();
	std::cout << "In charge of: ";
	std::cin >> InChargeOf();
	std::cout << "Reports to: ";
	std::cin >> ReportsTo();
}


Thank you a lot! :) Hope you will help me in the future with other problems
Unneeded use of inheritance, usage of multiple inheritance are seldom good, diamond problem here, derived classes depends on base class implementation.
In your code stream insertion operator is not polimorphic and because of class design it is impossible to make it one.
Topic archived. No new replies allowed.