classes inheritance

Pages: 12
Jan 29, 2017 at 8:43am
let's say I have two classes.

class A
class B

and I inherit what's in A to use it in B.

1
2
3
4
5
6
class B : public A
{
.
.
.
}


why do functions that I use from B in the source.cpp file is not identified?

I have files like this:
classA.h
classB.h
source.cpp

in int main(), I include both classes.

1
2
#include "classA.h"
#include "classB.h" 


Why does it not recognize my functions from B?
Last edited on Jan 29, 2017 at 8:44am
Jan 29, 2017 at 8:57am
Did you include "classA.h" in "classB.h"?

Show me what the file "classA.h" and "classB.h" look like.
Jan 29, 2017 at 9:38am
classA:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#pragma once

#include <string>
#include "Albahri.h"
using namespace std;

class Albahri : public Senator{

public:
	Albahri() {};
	char mostFreqLetter(string &cipher);
	string ShiftedCipher(string &cipher, int shiftAmount);
	bool fillDictionary(string shiftedCipher);
};


class B:
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
#pragma once

#include <string>

using namespace std;

class Senator {

public:
	Senator() {};
	Senator(string name) :m_name(name), m_attemps(26) {};
	string getEncryption(string filename, int shift);
	string getDecryption(string& ciphertext);
	string getName()
	{
		return m_name;
	}
	int getAttemps()
	{
		return m_attemps;
	}

protected:
	string m_name;
	int m_attemps;
};
Jan 29, 2017 at 9:43am
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#pragma once

#include <string>
#include "Albahri.h"
using namespace std;

class Albahri : public Senator{

public:
	Albahri() {};
	char mostFreqLetter(string &cipher);
	string ShiftedCipher(string &cipher, int shiftAmount);
	bool fillDictionary(string shiftedCipher);
};


Why does your file "Albahri.h" include itself or "Albahri.h"? Should "Albahri.h" include "Senator.h" instead?
Jan 29, 2017 at 10:07am
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#pragma once

#include <string>
#include "Senator.h"
using namespace std;

class Albahri : public Senator{

public:
	Albahri() {};
	char mostFreqLetter(string &cipher);
	string ShiftedCipher(string &cipher, int shiftAmount);
	bool fillDictionary(string shiftedCipher);
};


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
#pragma once

#include <string>

using namespace std;

class Senator {

public:
	Senator() {};
	Senator(string name) :m_name(name), m_attemps(26) {};
	string getEncryption(string filename, int shift);
	string getDecryption(string& ciphertext);
	string getName()
	{
		return m_name;
	}
	int getAttemps()
	{
		return m_attemps;
	}

protected:
	string m_name;
	int m_attemps;
};


still doesn't identify the functions of B inside main().
Jan 29, 2017 at 10:12am
Still doesn't identify the functions of B inside main().

So what do you do in your function main?
Jan 29, 2017 at 10:12am
.
Last edited on Jan 30, 2017 at 12:06am
Jan 29, 2017 at 10:21am
Your project has multiple compiler errors.

Firstly, the compiler keeps complaining I am missing message variable.

Also :
main.cpp(145) : error C2065: 'mostFreqLetter' : undeclared identifier
main.cpp(147) : error C2065: 'ShiftedCipher' : undeclared identifier
main.cpp(149) : error C2065: 'fillDictionary' : undeclared identifier


I think they are what you are looking for.

string Senator::getDecryption(string &cipher)

This method belongs to Senator class. Please note that Senator does not contain mostFreqLetter, shiftedCipher and fillDictionary. But Albahri class does.

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
string Senator::getDecryption(string &cipher)
{
	int shiftAmount = 0;
	string shiftedCipher;
	//from wikipedia
	char mostFreq[26] = { 'E', 'T', 'A', 'O', 'I', 'N', 'S', 'H', 'R', 'D',
		'L', 'C', 'U', 'M', 'W', 'F', 'G', 'Y', 'P', 'B',
		'V', 'K', 'J', 'X', 'Q', 'Z' };

	//find amount
	for (int i = 0; i < 26; i++)
	{
		shiftAmount = mostFreqLetter(cipher) - mostFreq[i];

		shiftedCipher = ShiftedCipher(cipher, shiftAmount);
		cout << "frequent letter being checked is: " << mostFreq[i] << endl;
		if (fillDictionary(shiftedCipher))
		{
			cout << "shifted cipher is: " << shiftedCipher << endl;
			cout << "cipher is still: " << cipher << endl;
			cout << "we found it! the cipher is: " << shiftedCipher << endl;
			break;
		}
		else
		{
			cout << "shifted cipher is: " << shiftedCipher << endl;
			cout << "cipher is still: " << cipher << endl;
			cout << "we couldn't decipher the word" << endl << endl;
		}
	}

	return shiftedCipher;
}
Last edited on Jan 29, 2017 at 10:22am
Jan 29, 2017 at 10:22am
If I friend class Albahri in class Senator. Will that solve the issue? or what should I do now?
Jan 29, 2017 at 10:24am
If I friend class Albahri in class Senator. Will that solve the issue? or what should I do now?

Friend classes may access private members of the other class, but it does not solve the problem when the member or the method cannot be found.

See my post above.
Jan 29, 2017 at 10:26am
I want to be able to use those functions in Senator. Is that feasible?
Jan 29, 2017 at 10:29am
I want to be able to use those functions in Senator. Is that feasible?

One option is to move necessary methods from Albahri to Senator class. Then you just let class Albahri inherit from class Senator as normal. Albahri will have all the members and methods that Senator has.
Jan 29, 2017 at 10:30am
The problem is that it's required to not touch Senator. I can only add methods in Albahri.
Jan 29, 2017 at 10:36am
The problem is that it's required to not touch Senator. I can only add methods in Albahri.

If that is the case, it is possible to do some hacking.

You define additional methods in Albahri class as normal. An Albahri class is actually a Senator class from inside.

Since you want it to work with both classes, that makes things easy.

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
string Senator::getDecryption(string &cipher)
{
	int shiftAmount = 0;
	string shiftedCipher;
	//from wikipedia
	char mostFreq[26] = { 'E', 'T', 'A', 'O', 'I', 'N', 'S', 'H', 'R', 'D',
		'L', 'C', 'U', 'M', 'W', 'F', 'G', 'Y', 'P', 'B',
		'V', 'K', 'J', 'X', 'Q', 'Z' };

	//find amount
	for (int i = 0; i < 26; i++)
	{
		shiftAmount = ((Albahri*)this)->mostFreqLetter(cipher) - mostFreq[i];

		shiftedCipher = ((Albahri*)this)->ShiftedCipher(cipher, shiftAmount);
		cout << "frequent letter being checked is: " << mostFreq[i] << endl;
		if (((Albahri*)this)->fillDictionary(shiftedCipher))
		{
			cout << "shifted cipher is: " << shiftedCipher << endl;
			cout << "cipher is still: " << cipher << endl;
			cout << "we found it! the cipher is: " << shiftedCipher << endl;
			break;
		}
		else
		{
			cout << "shifted cipher is: " << shiftedCipher << endl;
			cout << "cipher is still: " << cipher << endl;
			cout << "we couldn't decipher the word" << endl << endl;
		}
	}

	return shiftedCipher;
}


This way you treat a Senator object just like an Albahri object, and you are able to use methods from Albahri class.
Last edited on Jan 29, 2017 at 10:37am
Jan 29, 2017 at 7:58pm
In your main function you are only dealing with an object of type Senator. To access the functions specific to a derived class, you need an instance of the derived type.

Note that the change suggested by Mantor22 in his last post is very likely to result in undefined behavior, which is something to avoid.
Jan 29, 2017 at 8:14pm
In your main function you are only dealing with an object of type Senator. To access the functions specific to a derived class, you need an instance of the derived type.


Your code could be written like this, but it could be a little bit slower, but may be safer :

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
string Senator::getDecryption(string &cipher)
{
        Albahri albahri(*this);
	int shiftAmount = 0;
	string shiftedCipher;
	//from wikipedia
	char mostFreq[26] = { 'E', 'T', 'A', 'O', 'I', 'N', 'S', 'H', 'R', 'D',
		'L', 'C', 'U', 'M', 'W', 'F', 'G', 'Y', 'P', 'B',
		'V', 'K', 'J', 'X', 'Q', 'Z' };

	//find amount
	for (int i = 0; i < 26; i++)
	{
		shiftAmount = albahri.mostFreqLetter(cipher) - mostFreq[i];

		shiftedCipher = albahri.ShiftedCipher(cipher, shiftAmount);
		cout << "frequent letter being checked is: " << mostFreq[i] << endl;
		if (albahri.fillDictionary(shiftedCipher))
		{
			cout << "shifted cipher is: " << shiftedCipher << endl;
			cout << "cipher is still: " << cipher << endl;
			cout << "we found it! the cipher is: " << shiftedCipher << endl;
			break;
		}
		else
		{
			cout << "shifted cipher is: " << shiftedCipher << endl;
			cout << "cipher is still: " << cipher << endl;
			cout << "we couldn't decipher the word" << endl << endl;
		}
	}

	return shiftedCipher;
}


The downside is that if one of the functions in Albahri class update some member of the temporary Albahri object, which is most likely albahri.fillDictionary, you may need to do (*this) = albahri; to update the real Senator object.

And about my method, this is hacking, so yes it might cause undefined behavior. I am saying if the size of Albahri and Senator are the same (basic condition), he/she might benefit from this hacking if he/she uses it correctly.
Jan 29, 2017 at 8:24pm
I am saying if the size of Albahri and Senator are the same (basic condition), he/she might benefit from this hacking if he/she uses it correctly.

All that is required for the OP to gain access to methods specific to type Albahri in main is to use an object of type Albahri.

Saying "If you use this incorrect way correctly, it may be beneficial" is bollocks.
Jan 29, 2017 at 8:29pm
All that is required for the OP to gain access to methods specific to
type Albahri in main is to use an object of type Albahri.

I don't get it. If he wants to use an object of type Senator and he wants to use methods mostFreqLetter, shiftedCipher and fillDictionary (which belong to Albahri class), what is your choice? And you are not allowed to modify the original Senator class.

Also why was my post reported?

DeathLeap wrote:
I want to be able to use those functions in Senator. Is that feasible?


P.S : My way is only for people who are experienced. I don't force them, and there might be better way to do it if you state it more clearly.
Last edited on Jan 29, 2017 at 8:32pm
Jan 29, 2017 at 8:49pm
I don't get it. If he wants to use an object of type Senator and he wants to use methods mostFreqLetter, shiftedCipher and fillDictionary (which belong to Albahri class), what is your choice? And you are not allowed to modify the original Senator class.


Somehow it didn't register that the OP was attempting to use derived class methods inside a base class method. That doesn't make your advice any more palatable.

To the OP: You cannot use methods of a derived class safely in a base class if the interface for those (virtual) methods does not exist in the base class. In other words, what you want to do is not practical without changing the Senator type.

Generally, you would include either pure virtual versions of those functions in the base class or virtual functions that would serve as default behavior, but in no instance there would you be able to access derived class methods via a base class instance. You would need a derived class instance, although it may be referenced via a pointer-to-base-class or a reference-to-base-class.
Jan 29, 2017 at 8:54pm
Generally, you would include either pure virtual versions of those functions in the base class or virtual functions that would serve as default behavior.

I am not against that, how would we modify the base class (Senator) when DeathLeap says it should not be modified? But I am not sure if DeathLeap wants to add methods mostFreqLetter, shiftedCipher and fillDictionay to his Senator class, we are not clear what the real assignment is.
Pages: 12