简体   繁体   中英

How do I have an array as a private class member and ensure proper encapsulation?

I'm making a program for enciphering and deciphering text phrases that utilizes a 2D table. I have a single class that holds everything necessary for the cipher. However, I'm running into trouble when dealing with the table. I've got it constructed okay enough, but I'm having trouble encapsulating it in the class. I feel like it should be constructed automatically when an object is created, but right now I'm having to call it in through the main.

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

class Cipher {
    public:
        Cipher();
        Cipher(string key);
        Cipher(string key, string message);

        void buildTable(char table[][26]);
        void newKey(string keyphrase);
        void inputMessage();
        string encipher(string message);
        string decipher(string message);
        string getPlainText() const;
        string getCipherText() const;

    private:
        string key;
        string plaintext;
        string ciphertext;
};

. . . .

void Cipher::buildTable(char table[][26]) {
    char alphabet[26] = {'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'};

    int alphaIndex = 0;

    for (int index1 = 0; index1 < 26; index1++) {
        for (int index2 = 0; index2 < 26; index2++) {   

            if ((index1 + index2) < 26) {
                alphaIndex = index1 + index2;
                table[index1][index2] = alphabet[alphaIndex];
            }
            else
                alphaIndex = 0;

            while (((index1 + index2) > 25) && index2 < 26) {
                table[index1][index2] = alphabet[alphaIndex];
                index2++;
                alphaIndex++;
            }           
        }               
    }
}

This table is key to the program functioning, and there is no reason for it to be changed. I tried including it as a private member, but ran into a lot of trouble. Should I be including this in the constructors, or what is the proper way to encapsulate this?

The "char table[][26]" that you have, I recommend to make it a private member of your class. And when in the constructor you should initialize it. Your "buildTable" member function should not take the array as a parameter, but instead it should initialize your private 2 dimensional array. By looking at your code, I don't see any reason as to why you should have your table on the stack of "buildTable" function.

This looks like a job for an Initialize On First Use function.

class Cipher {
    public:
        // ...
    private:
        using table_type = char[26][26];
        // Or for C++03 mode,
        // typedef char table_type[26][26];

        static void buildTable(table_type& table);
        static const table_type& getTable();
        // ...
}

const Cipher::table_type& Cipher::getTable() {
    static table_type the_table;
    if (the_table[0][0] == '\0')
        buildTable(the_table);
    return the_table;
}

I prefer to leave the constructor parameters to feed-in the minimum class configuration values. So I would leave it as a private member. As for the values, I don't see why to re calculate them every time an instance is created, if they won't change, you just need to calculate them once and hard code them into the cpp file.

The *.h file:

class Cipher {
    ...
private:
    ...
    static const int table[26][26];
};

The *.cpp file:

...
const int Cipher::table[26][26] = { ... };
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM