Introduction

This page contains an interactive story where the reader will take part of a C++ coding quiz. It is the second part of a series started here. The reader will be asked to write C++ code in an interactive quiz format. This quiz is designed for people preparing for a job interview or willing to improve their coding skills. The C++ topics and keywords discussed in this quiz are Class, Singleton, Operator, Static.

What do you do ?

=> Start

Start

You successfully solved the first coding challenge. Scott indicates that you are now ready to try the second coding challenge. His team is writing object oriented code and he would like to test your capabilities on this subject. He asks you take the test, are you ready ?

What do you do ?

=> Yes

=> No

No

You decide that the C++ language is complex and even more when it comes to object oriented programming. You decide to refuse and take some time to read more about this topic. Scott understands and invite you to come back when you are ready.

What do you do ?

=> Go home

Yes

You are ready, see below what you need to code.

Write a class named "OneConfig" which can at most have one instance. This design pattern is called "Singleton".

What do you do ?

=> Start coding

Quiz Question 1

You understand the instruction and write an empty class OneConfig.

class OneConfig {

}; 

int main() {

  OneConfig a;
  OneConfig b;

}

As you would expect it, the class OneConfig can be instanciated multiple times. How can you do to stop OneConfig to be instanciated ?

What do you do ?

=> Learn how to do it

=> You know how to do it

C++ Private Constructor

After searching a way to allow only one instance of the class OneConfig to be created, you decide that a good step forward will be first to not allow any instances to be created. To do that, you declare the constructor private.

class OneConfig {

  private : 
    OneConfig(){};

}; 

int main() {

  OneConfig a;
  OneConfig b;

}

As expected, the compiler does not allow the creation of an instance of the class OneConfig and correctly generates a compiler errors for the above code.

 error: calling a private constructor of class 'OneConfig'
  OneConfig a;
            ^
./main_quiz_2.cpp:4:5: note: declared private here
    OneConfig(){};
    ^
./main_quiz_2.cpp:11:13: error: calling a private constructor of class 'OneConfig'
  OneConfig b;
            ^
./main_quiz_2.cpp:4:5: note: declared private here
    OneConfig(){};
    ^
2 errors generated.

What do you do ?

=> Next

Quiz Question 2

That’s great, now you have a code not allowing any instances of the class OneConfig to be created. As a next step, you decide to code a mechanism allowing only one instance to be created. Here is the last version of your code.

class OneConfig {

  private : 
    OneConfig(){};

}; 

int main() {

}

What do you do ?

=> Learn how to do it

=> You know how to do it

C++ Static Method

You think for a moment and then remember that with the keyword static it is possible to associate a method to a class rather than its instances. That means that from the code, having access to a class is enough to invoke a its static method. You decide to use this mechanism and produce the below code. The logic of this code allows the creation of one instance and returns it in every call of the function OneConfig::getInstance().

class OneConfig {

  public :
    static OneConfig* getInstance() {
      if (OneConfig::instance == nullptr) {
        OneConfig::instance = new OneConfig();
      }
      return OneConfig::instance;
    }

  private : 
    OneConfig(){};
    static OneConfig* instance; 

}; 

int main() {

  OneConfig* p = OneConfig::getInstance();

}

What do you do ?

=> Next

Quiz Question 3

Super, now you are able to produce a unique instance of the class OneConfig which will be returned at every call of the function OneConfig::getInstance(). When testing your code, you notice that some syntax permits the creation of a second instance.

class OneConfig {

  public :
    static OneConfig* getInstance() {
      if (OneConfig::instance == nullptr) {
        OneConfig::instance = new OneConfig();
      }
      return OneConfig::instance;
    }

  private : 
    OneConfig(){};
    static OneConfig* instance; 

}; 

int main() {

  OneConfig* p = OneConfig::getInstance();
  OneConfig a(*p);
  OneConfig b = a;

}

The above code creates in total three instances of the class OneConfig. You want to prohibit this ability and instead get a compiler error.

What do you do ?

=> Learn how to do it

=> You know how to do it

C++ Private Copy-Constructor

Since you want to have the control over how the instance behaves when getting assigned or copied, you decide to override the logic of the default generated assignment operator and copy-constructor and make them private. You work on this and produce the below code.

class OneConfig {

  public :
    static OneConfig* getInstance() {
      if (OneConfig::instance == nullptr) {
        OneConfig::instance = new OneConfig();
      }
      return OneConfig::instance;
    }

  private : 
    OneConfig(){};
    OneConfig(const OneConfig& o);
    OneConfig& operator=(const OneConfig&);    
    static OneConfig* instance; 

}; 

int main() {

  OneConfig* p = OneConfig::getInstance();
  OneConfig a(*p);
  OneConfig b = a;

}

Great! Now the compiler generates errors when trying to copy or assign a OneConfig object. See below the compiler errors :

error: calling a private constructor of class 'OneConfig'
  OneConfig a(*p);
            ^
./main_quiz_2.cpp:13:5: note: declared private here
    OneConfig(const OneConfig& o);
    ^
./main_quiz_2.cpp:23:17: error: calling a private constructor of class 'OneConfig'
  OneConfig b = a;
                ^
./main_quiz_2.cpp:13:5: note: declared private here
    OneConfig(const OneConfig& o);
    ^
2 errors generated.

What do you do ?

=> Next

End

You finally reached the end of the coding test. You show the result to Scott and answer correctly all his questions.

Congratulations ! You successfully completed this C++ coding quiz