classes inheritance

Pages: 12
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
Did you include "classA.h" in "classB.h"?

Show me what the file "classA.h" and "classB.h" look like.
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;
};
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?
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().
Still doesn't identify the functions of B inside main().

So what do you do in your function main?
.
Last edited on
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
If I friend class Albahri in class Senator. Will that solve the issue? or what should I do now?
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.
I want to be able to use those functions in Senator. Is that feasible?
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.
The problem is that it's required to not touch Senator. I can only add methods in Albahri.
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
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.
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.
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.
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
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.
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