Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8164425
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 6, 20262026-06-06T19:18:49+00:00 2026-06-06T19:18:49+00:00

I am having a hard time figuring how to design classes that can’t initialize

  • 0

I am having a hard time figuring how to design classes that can’t initialize all their internal members in the constructor. I know that this should be something basic and discussed all over the net, but I’m not sure what to look for. So, for example, please consider the following code:

#include <iostream>

class Workhorse
{
public:
    void SetData (const int &data)
    {
        this->data = data;
    }

    int GetData () const
    {
        return this->data;
    }

private:
    int data;
};

class Worker
{
public:
    Worker ()
    {
    }
    void Initialize (const int &data)
    {
        horse.SetData(data);
    }
    void Action () const
    {
        std::cout << horse.GetData() << std::endl;
    }

private:
    Workhorse horse;
};

int main ()
{
    Worker worker;
    worker.Initialize(3);
    worker.Action();
    return 0;
}

I want to prevent the workers from calling any methods without first calling Initialize(). The layman’s implementation would be to add an isInitialized flag in the Worker class, set it to true in Initialize() and test it at the beginning of each public method (maybe also in the protected / private ones, if we introduce some inheritance?). Unfortunately, this seems a bit cumbersome and hard to maintain. Also, it’s just awful to repeat an if statement in all methods. I haven’t even began to ponder about thread safety issues, but, right now, I’m only implementing a single-threaded application. Is there a smarter way to design this?


EDIT: OK, I chose a dumb design as an example, which, indeed, is flawed. Let me try to give a clearer picture of what I have:

#include <iostream>

class PublicKeyCryptoProvider
{
public:
    struct PublicKey
    {
        int shared;
    };
    struct PrivateKey
    {
        int secret;
    };

    int Encrypt (const int &plaintext) const
    {
        int ciphertext;
        //apply encryption algorithm on plaintext
        ciphertext = plaintext * this->pk.shared;
        return ciphertext;
    }

    int Decrypt (const int &ciphertext) const
    {
        int plaintext;
        //apply decryption algorithm on ciphertext
        plaintext = ciphertext / this->sk.secret;

        return plaintext;
    }

    void GenerateKeys ()
    {
        this->pk.shared = 4;
        this->sk.secret = 4;
        //generate pk and sk
    }

    void SetPublicKey (const PublicKey &pk)
    {
        this->pk = pk;
    }

    const PublicKey &GetPublicKey () const
    {
        return this->pk;
    }

private:
    PublicKey pk;
    PrivateKey sk;
};

int main ()
{
    /* scenario 1: */
    PublicKeyCryptoProvider cryptoProvider;
    cryptoProvider.GenerateKeys();
    std::cout << cryptoProvider.Decrypt(cryptoProvider.Encrypt(3)) << std::endl;
    /* /scenario 1: */

    /* scenario 2: */
    PublicKeyCryptoProvider cryptoProvider1;
    cryptoProvider1.GenerateKeys();

    PublicKeyCryptoProvider cryptoProvider2;
    cryptoProvider2.SetPublicKey(cryptoProvider1.GetPublicKey());

    int ciphertext = cryptoProvider2.Encrypt(3);
    std::cout << cryptoProvider1.Decrypt(ciphertext) << std::endl;

    //now let's do something bad...
    std::cout << cryptoProvider2.Decrypt(ciphertext) << std::endl;
    /* /scenario 2: */

    return 0;
}

Obviously, you can imagine real life examples where scenario 2 is perfectly valid. Given the above situation, is there any better option than adding a canDecrypt flag inside the PublicKeyCryptoProvider class, which is set to true when generating keys and then tested at the beginning of the decrypt method? I have to mention that this is a very simple example, because, in my case, the PublicKeyCryptoProvider can perform faster encryptions if it is the owner of the secret key and it has much more public methods, so I would be doomed to test the flag more than a couple of times… Also, I have a client – server mockup scenario where the server exposes a bunch of public methods for the client, but the client can only call the methods after it has called the Initialize() method on the server…

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-06T19:18:50+00:00Added an answer on June 6, 2026 at 7:18 pm

    Great question! Its always good to make an API that is hard to use wrong, and as you are observing classes that are not fully constructed are dangerous, hard to use correctly and easy to use wrong. They set ourselves & others up for failure. I’ve done some refactoring on your second example to come up with a safer design that won’t even allow your “do something bad” code.

    The general idea was that PublicKeyCryptoProvider had too many responsibilities ( violation of SRP ):

    • Key generation
    • Key storage
    • Encryption
    • Decryption

    Each one of the responsibilities has been delegated out. Now the PublicKeyCryptoProvider is more responsible for giving you the tools necessary to do encryption/decryption & key management.

    #include <iostream>
    #include <utility>
    
    struct PublicKey
    {
        int shared;
    };
    struct PrivateKey
    {
        int secret;
    };
    
    struct KeyPair
    {
        PublicKey public_key;
        PrivateKey private_key;
    };
    
    
    struct Encryptor
    {
        Encryptor( PublicKey shared_ )
         : shared( shared_ )
        {}
    
        int Encrypt (const int &plaintext) const
        {
            int ciphertext;
            //apply encryption algorithm on plaintext
            ciphertext = plaintext * shared.shared;
            return ciphertext;
        }
    
    private:
        PublicKey shared;
    };
    
    struct Decryptor
    {
        Decryptor( PrivateKey secret_ )
         : secret( secret_ )
        {}
    
        int Decrypt (const int &ciphertext) const
        {
            int plaintext;
            //apply decryption algorithm on ciphertext
            plaintext = ciphertext / secret.secret;
    
            return plaintext;
        }
    
    private:
        PrivateKey secret;
    };
    
    class PublicKeyCryptoProvider
    {
    public:
    
        KeyPair GenerateKeys()
        {
            KeyPair keys;
    
            //generate pk and sk
            keys.public_key.shared = 4;
            keys.private_key.secret = 4;
    
            return keys;
        }
    
    
        Decryptor BuildDecryptor( PrivateKey key )
        {
            return Decryptor( key );
        }
    
        Encryptor BuildEncryptor( PublicKey key )
        {
            return Encryptor( key );
        }
    
    
    /* These are replaced by directly building an Encryptor/Decryptor
     when you have a public or private key.
    
        void SetPublicKey (const PublicKey &pk)
        {
            this->pk = pk;
        }
    
        const PublicKey &GetPublicKey () const
        {
            return this->pk;
        }
    */
    
    };
    
    int main ()
    {
        /* scenario 1: */
        PublicKeyCryptoProvider cryptoProvider;
        auto keys = cryptoProvider.GenerateKeys();
        auto decryptor = cryptoProvider.BuildDecryptor(keys.private_key);
        auto encryptor = cryptoProvider.BuildEncryptor(keys.public_key);
    
        std::cout << decryptor.Decrypt( encryptor.Encrypt(3) ) << std::endl;
        /* /scenario 1: */
    
        /* scenario 2: */
        PublicKeyCryptoProvider cryptoProvider1;
        auto keys1 = cryptoProvider1.GenerateKeys();
    
        PublicKeyCryptoProvider cryptoProvider2;
        auto encryptor2 = cryptoProvider2.BuildEncryptor(keys.public_key);
    
        int ciphertext = encryptor2.Encrypt(3);
        std::cout << decryptor.Decrypt(ciphertext) << std::endl;
    
        // I Can't do anything bad - the API has protected me from doing bad things! Yeah!
        //std::cout << cryptoProvider2.Decrypt(ciphertext) << std::endl;
        /* /scenario 2: */
    
        return 0;
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm having a hard time figuring out how i can add an arraylist into
I'm having a hard time figuring out why lseek doesn't work properly. Basically all
Below is a method that I'm having a hard time figuring out how to
I'm having a hard time figuring out how I can get my select element
I am new here, but I am having hard time figuring out how to
Having a hard time figuring out why this alert code is being called once
Having a hard time figuring out the best way to do this... I have
I am having a hard time figuring out how to get cascading drop down
I am having a hard time figuring out what flags to pass to g++
I am having a hard time figuring out how to show an Image (or

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.