How to use member functions declared in header and source files in the main method.

I'm writing a program to translate morse code and I have it working perfectly but I need it to be spread across multiple files with a header and two source files.
I'm have spent hours and hours pouring over my book to try and understand how to figure out the methods for calling functions from other files but it never ever works and I feel like I'm playing darts in the dark.

Here is my one file version.
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
  #include <iostream>
#include <sstream>
#include <string>
#include <unordered_map>


int main()
{
	std::unordered_map<std::string, char> decode = {
		{ ".-", 'A' },{ "-...", 'B' },{ "-.-.", 'C' },{ "-..", 'D' },{ ".", 'E' },
		{ "..-.", 'F' },{ "--.", 'G' },{ "....", 'H' },{ "..", 'I' },{ ".---", 'J' },{ "-.-", 'K' },
		{ ".-..", 'L' },{ "--", 'M' },{ "-.", 'N' },{ "---", 'O' },{ ".--.", 'P' },{ "--.-", 'Q' },
		{ ".-.", 'R' },{ "...", 'S' },{ "-", 'T' },{ "..-", 'U' },{ "...-", 'V' },{ ".--", 'W' },
		{ "-..-", 'X' },{ "-.--", 'Y' },{ "--..", 'Z' },{ ".----", '1' },{ "..---", '2' },{ "...--", '3' },{ "....-", '4' },
		{ ".....", '5' },{ "-....", '6' },{ "--...", '7' },{ "---..", '8' },{ "----.", '9' },{ "-----", '0' },
		{ ".-.-.-", '.' },{ "--..--", ',' },{ "---...", ':' },{ "..--..", '?' },{ "-...-", '-' },
		{ "-..-.", '/' },{ "/", ' ' }
	};
	std::string input;
	std::cout << "Enter morse code to be translated to english. \n";
	getline(std::cin, input);

	std::istringstream iss(input);
	
	iss.str(input);
	int n = input.length();

	
	for (int i = 0; i<n; i++ ){
		std::string val;
		iss >> val;
	std::unordered_map<std::string, char>::const_iterator got = decode.find(val);
		
		std::cout << got->second;
		
	}
	std::cout << std::endl;
	system("Pause");
	return 0;
}


And this is the unfinished multi file version.

Morse.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef _MORSE_H
#define _MORSE_H 3710201612

#define MORSE_SET 45

#include <string>
#include <unordered_map>


class MorseCode
{
  public:
    MorseCode ();

    std::string enCode(const char&) const;
    char   deCode(const std::string&) const;

  private:
	std::unordered_map<char, std::string> encodeMap;
    std::unordered_map<std::string,char> decodeMap;
};

#endif 


Morse.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
#include <iostream>
#include <string>
#include <unordered_map>


#include "Morse.h"



MorseCode::MorseCode() : encodeMap{
	{ 'A', ".-" },{ 'B', "-..." },{ 'C', "-.-." },{ 'D', "-.." },{ 'E', "." },
	{ 'F', "..-." },{ 'G', "--." },{ 'H', "...." },{ 'I', ".." },{ 'J', ".---" },{ 'K', "-.-" },
	{ 'L', ".-.." },{ 'M', "--" },{ 'N', "-." },{ 'O', "---" },{ 'P', ".--." },{ 'Q', "--.-" },
	{ 'R', ".-." },{ 'S', "..." },{ 'T', "-" },{ 'U', "..-" },{ 'V', "...-" },{ 'W', ".--" },
	{ 'X', "-..-" },{ 'Y', "-.--" },{ 'Z', "--.." },{ '1', ".----" },{ '2', "..---" },{ '3', "...--" },{ '4', "....-" },
	{ '5', "....." },{ '6', "-...." },{ '7', "--..." },{ '8', "---.." },{ '9', "----." },{ '0', "-----" },
	{ '.', ".-.-.-" },{ ',', "--..--" },{ ':', "---..." },{ '?', "..--.." },{ '-', "-...-" },
	{ '/', "-..-." }
} 
{
	
}



MorseCode::MorseCode() : decodeMap{
	{ ".-", 'A' }, { "-...", 'B' },{ "-.-.", 'C' },{ "-..", 'D' },{ ".", 'E' },
	{ "..-.", 'F' },{ "--.", 'G' },{ "....", 'H' },{ "..", 'I' },{ ".---", 'J' },{ "-.-", 'K' },
	{ ".-..", 'L' },{ "--", 'M' },{ "-.", 'N' },{ "---", 'O' },{ ".--.", 'P' },{ "--.-", 'Q' },
	{ ".-.", 'R' },{ "...", 'S' },{ "-", 'T' },{ "..-", 'U' },{ "...-", 'V' },{ ".--", 'W' },
	{ "-..-", 'X' },{ "-.--", 'Y' },{ "--..", 'Z' },{ ".----", '1' },{ "..---", '2' },{ "...--", '3' },{ "....-", '4' },
	{ ".....", '5' },{ "-....", '6' },{ "--...", '7' },{ "---..", '8' },{ "----.", '9' },{ "-----", '0' },
	{ ".-.-.-", '.' },{ "--..--", ',' },{ "---...", ':' },{ "..--..", '?' },{ "-...-", '-' },
	{ "-..-.", '/' }, { " ", ' '}
}
{
	
}



std::string MorseCode::enCode(const char&) const
{
	//unordered_map<string, char>const_iterator got = encodeMap.find(enCode); 
	//std::unordered_map<std::string, char>::const_iterator got = encodeMap.find (enCode);
	// (got == encodeMap.end())
		//std::cout << "not found";
	//else
		//std::cout << got->first << " is " << got->second;

	//std::cout << std::endl;
	std::string input;
	//auto thing = encodeMap.find(input);
	return std::string();
}

char MorseCode::deCode(const std::string &) const
{
	std::string input;
	return 0;
}


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
#include <iostream>
#include <sstream>
#include <string>
#include <unordered_map>

#include "Morse.h"
#include "Morse.cpp"


int main() {
	MorseCode m;
	std::string input;
	std::cout << "Enter morse code to be translated to english. \n";
	getline(std::cin, input);

	std::istringstream iss(input);

	iss.str(input);
	int n = input.length();


	for (int i = 0; i<n; i++) {
		std::string val;
		iss >> val;
		std::unordered_map<std::string, char>::const_iterator got = m.decodeMap.find(val);

		std::cout << got->second;

	}
	std::cout << std::endl;
	system("Pause");
	return 0;
};
Last edited on
I don't see anything immediately wrong there.

If you could be more specific about what problems you're having, and what errors you're getting, we might be able to help.
What I can't figure out is how to access the decodeMap unordered_map in my main. Like how do I create an instance of decodeMap in main so that I can search through it?
Line 25 in my main gives me an error that decodeMap is inaccessible which makes sense because it is private so how do I access the version created in Morse.cpp?
Also in Morse.cpp I get the error "Error C2084 function 'MorseCode::MorseCode(void)' already has a body" Now I realize that this is happening because I have two separate instances of MorseCode::MorseCode() : "mapname" but I have to define decodeMap and encodeMap so how do I do that without creating two separate bodies?

I am so frustrated with this. My textbook provides syntax examples that just do not work with the situations that my professor forces us to be in. Am I just supposed to guess random code for hours until it works? Why do professors not give similar code examples so I can learn it before I blindly plug random attempts in? So frustrated by this.
Last edited on
This is what the main() knows about MorseCode:
1
2
3
4
5
6
7
class MorseCode
{
  public:
    MorseCode (); // #1

    std::string enCode(const char&) const; // #2
    char   deCode(const std::string&) const; // #3 

That is called interface.

The main() can:
1. create objects: MorseCode foo;
2. call two functions of such objects:
1
2
auto bar = foo.enCode( '?' );
auto gaz = foo.deCode( bar );

Do these member functions perform equivalent operations to the uo_map::find()?

Outsiders should not care what is inside (private) in objects. They must use the interface. What should the interface of MorseCode offer for the users?


PS. You do implement the constructor of MorseCode twice. That is an error. Consider this:
1
2
3
4
5
6
7
8
9
class Foo {
  Foo();
  int x;
  char y;
};

Foo::Foo()
 : x( 42 ), y( 'n' ) // member initializer list
{}
So I think I have figured out the syntax there.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
MorseCode::MorseCode()
	: decodeMap(), encodeMap()
{
	decodeMap = { { ".-", 'A' }, { "-...", 'B' }, { "-.-.", 'C' }, { "-..", 'D' }, { ".", 'E' },
	{ "..-.", 'F' }, { "--.", 'G' }, { "....", 'H' }, { "..", 'I' }, { ".---", 'J' }, { "-.-", 'K' },
	{ ".-..", 'L' }, { "--", 'M' }, { "-.", 'N' }, { "---", 'O' }, { ".--.", 'P' }, { "--.-", 'Q' },
	{ ".-.", 'R' }, { "...", 'S' }, { "-", 'T' }, { "..-", 'U' }, { "...-", 'V' }, { ".--", 'W' },
	{ "-..-", 'X' }, { "-.--", 'Y' }, { "--..", 'Z' }, { ".----", '1' }, { "..---", '2' }, { "...--", '3' }, { "....-", '4' },
	{ ".....", '5' }, { "-....", '6' }, { "--...", '7' }, { "---..", '8' }, { "----.", '9' }, { "-----", '0' },
	{ ".-.-.-", '.' }, { "--..--", ',' }, { "---...", ':' }, { "..--..", '?' }, { "-...-", '-' },
	{ "-..-.", '/' }, { " ", ' ' } };
	encodeMap = { { 'A', ".-" }, { 'B', "-..." }, { 'C', "-.-." }, { 'D', "-.." }, { 'E', "." },
	{ 'F', "..-." }, { 'G', "--." }, { 'H', "...." }, { 'I', ".." }, { 'J', ".---" }, { 'K', "-.-" },
	{ 'L', ".-.." }, { 'M', "--" }, { 'N', "-." }, { 'O', "---" }, { 'P', ".--." }, { 'Q', "--.-" },
	{ 'R', ".-." }, { 'S', "..." }, { 'T', "-" }, { 'U', "..-" }, { 'V', "...-" }, { 'W', ".--" },
	{ 'X', "-..-" }, { 'Y', "-.--" }, { 'Z', "--.." }, { '1', ".----" }, { '2', "..---" }, { '3', "...--" }, { '4', "....-" },
	{ '5', "....." }, { '6', "-...." }, { '7', "--..." }, { '8', "---.." }, { '9', "----." }, { '0', "-----" },
	{ '.', ".-.-.-" }, { ',', "--..--" }, { ':', "---..." }, { '?', "..--.." }, { '-', "-...-" },
	{ '/', "-..-." } };
	}
Last edited on
So I still see no way to access the unordered maps... How do I loop through them if they are private?
I feel like I should be defining the member function deCode to iterate through the decodeMap but it can't because it can't access it. How can this be done?
A member of a class can access other members of the same class.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Foo {
  int x;
public:
  Foo() : x( 42 ) {}

  int bar() {
    return x / 2; // Does this compile?
  }
};

int main() {
  Foo gaz;
  int test = gaz.bar();
  return 0;
}



Your syntax initializes the two members on line 2 as empty maps, and then assigns values to already initialized objects within the body of the constructor (lines 4-19).

Initialize directly:
1
2
3
4
5
6
MorseCode::MorseCode()
:	encodeMap { { 'A', ".-" }, { 'B', "-..." } },
	decodeMap { { ".-", 'A' }, { "-...", 'B' } }
{
  // nothing here
}


One more thing, that your compiler should have mentioned: the order of initialization is dictated by definition of the class. You had:
class MorseCode
1
2
3
4
5
{
  private:
    std::unordered_map<char, std::string> encodeMap;
    std::unordered_map<std::string,char> decodeMap;
};

The encodeMap is thus initialized before decodeMap.

You wrote:
1
2
3
4
MorseCode::MorseCode()
	: decodeMap(), encodeMap()
{
}

but the compiler must do:
1
2
3
4
MorseCode::MorseCode()
	: encodeMap(), decodeMap()
{
}



Modern C++ has also default member initializer syntax:
1
2
3
4
5
6
7
8
9
10
11
12
class MorseCode
{
  public:
    MorseCode () = default;

    std::string enCode(const char&) const;
    char   deCode(const std::string&) const;

  private:
    std::unordered_map<char, std::string> encodeMap { { 'A', ".-" }, { 'B', "-..." } };
    std::unordered_map<std::string,char> decodeMap { { ".-", 'A' }, { "-...", 'B' } };
};
Topic archived. No new replies allowed.