Use of public destructor when the constructor is private - c++

I have seen code where the constructor has been declared as private while the destructor is public. What is the use of such a declaration? Is the destructor required to be public so that during inheritance the calls can be possible or is it a bug in the code?
The question might seem to be a bit short on information, but what I really want to know is if having a public destructor when the constructor is required to be private abides by the C++ rules?

Short Answer
Creating a constructor as private but the destructor as public has many practical uses.
You can use this paradigm to:
Enforcing reference counting (See Hitesh Vaghani's example).
Implement the singleton pattern
Implement the factory pattern.
Long Answer
Above I hinted that you can use private constructors and destructors to implement several design patterns. Well, here's how...
Reference Counting
Using private destructor within an object lends itself to a reference counting system. This lets the developer have stronger control of an objects lifetime.
class MyReferenceObject
{
public:
static MyReferenceObject* Create()
{
return new MyReferenceObject();
}
void retain()
{
m_ref_count++;
}
void release()
{
m_ref_count--;
if (m_ref_count <= 0)
{
// Perform any resource/sub object cleanup.
// Delete myself.
delete this; // Dangerous example but demonstrates the principle.
}
}
private:
int m_ref_count;
MyReferenceObject()
{
m_ref_count = 1;
}
~MyReferenceObject() { }
}
int main()
{
new MyReferenceObject(); // Illegal.
MyReferenceObject object; // Illegal, cannot be made on stack as destructor is private.
MyReferenceObject* object = MyReferenceObject::Create(); // Creates a new instance of 'MyReferenceObject' with reference count.
object->retain(); // Reference count of 2.
object->release(); // Reference count of 1.
object->release(); // Reference count of 0, object deletes itself from the heap.
}
This demonstrates how an object can manage itself and prevent developers from corrupting the memory system. Note that this is a dangerous example as MyReferenceObject deletes itself, see here for a list of things to consider when doing this.
Singleton
A major advantage to private constructors and destructors within a singleton class is that enforces the user to use it in only the manner that the code was design. A rogue singleton object can't be created (because it's enforced at compile time) and the user can't delete the singleton instance (again, enforced at compile time).
For example:
class MySingleton
{
public:
MySingleton* Instance()
{
static MySingleton* instance = NULL;
if (!instance)
{
instance = new MySingleton();
}
return instance;
}
private:
MySingleton() { }
~MySingleton() { }
}
int main()
{
new MySingleton(); // Illegal
delete MySingleton::Instance(); // Illegal.
}
See how it is almost impossible for the code to be misused. The proper use of the MySingleton is enforce at compile time, thus ensuring that developers must use MySingleton as intended.
Factory
Using private constructors within the factory design pattern is an important mechanism to enforce the use of only the factory to create objects.
For example:
class MyFactoryObject
{
public:
protected:
friend class MyFactory; // Allows the object factory to create instances of MyFactoryObject
MyFactoryObject() {} // Can only be created by itself or a friend class (MyFactory).
}
class MyFactory
{
public:
static MyFactoryObject* MakeObject()
{
// You can perform any MyFactoryObject specific initialisation here and it will carry through to wherever the factory method is invoked.
return new MyFactoryObject();
}
}
int main()
{
new MyFactoryObject(); // Illegal.
MyFactory::MakeObject(); // Legal, enforces the developer to make MyFactoryObject only through MyFactory.
}
This is powerful as it hides the creation of MyFactoryObject from the developer. You can use the factory method to perform any initilisation for MyFactoryObject (eg: setting a GUID, registering into a DB) and anywhere the factory method is used, that initilisation code will also take place.
Summary
This is just a few examples of how you can use private constructors and destructors to enforce the correct use of your API. If you want to get tricky, you can combine all these design patterns as well ;)

First thing: the destructor can be private.
having a public destructor when the constructor is required to be
private abides by the C++ rules?
It's totally working in C++. In fact, a great example of this scenario is the singleton pattern, where the constructor is private and the destructor is public.

In reverse order.
Is the destructor required to be public so that during inheritance the calls can be possible or is it a bug in the code?
Actually, for inheritance to work the destructor should be at least protected. If you inherit from a class with a private destructor, then no destructor can be generated for the derived class, which actually prevents instantiation (you can still use static methods and attributes).
What is the use of such declaration?
Note that even though the constructor is private, without further indication the class has a (default generated) public copy constructor and copy assignment operator. This pattern occurs frequently with:
the named constructor idiom
a factory
Example of named constructor idiom:
class Angle {
public:
static Angle FromDegrees(double d);
static Angle FromRadian(double d);
private:
Angle(double x): _value(x) {}
double _value;
};
Because it is ambiguous whether x should be precised in degrees or radians (or whatever), the constructor is made private and named method are provided. This way, usage makes units obvious:
Angle a = Angle::FromDegrees(360);

You make constructor private if you want to prevent creating more then one instance of your class. That way you control the creation of intances not their destruction. Thus, the destructor may be public.

One example in my head, let's say you want to limit the class instance number to be 0 or 1.
For example, for some singleton class, you want the application can temprary destroy the object to rducue memory usage. to implement this constructor will be private, but destructor will be public. see following code snippet.
class SingletoneBigMemoryConsumer
{
private:
SingletoneBigMemoryConsumer()
{
// Allocate a lot of resource here.
}
public:
static SingletoneBigMemoryConsumer* getInstance()
{
if (instance != NULL)
return instance;
else
return new SingletoneBigMemoryConsumer();
}
~SingletoneBigMemoryConsumer()
{
// release the allocated resource.
instance = NULL;
}
private:
// data memeber.
static SingletoneBigMemoryConsumer* instance;
}
//Usage.
SingletoneBigMemoryConsumer* obj = SingletoneBigMemoryConsumer::getInstance();
// You cannot create more SingletoneBigMemoryConsumer here.
// After 1 seconds usage, delete it to reduce memory usage.
delete obj;
// You can create an new one when needed later

The owner of an object needs access to the destructor to destroy it. If the constuctors are private, there must be some accessible function to create an object. If that function transferes the ownership of the constructed object to the caller ( for example return a pointer to a object on the free store ) the caller must have the right to access the destructor when he decides to delete the object.

Related

How horrible is Static-Casting Base class to Derived class in order to call destructor in tests (for tests)?

Preface: I am aware that the following is a very dirty hack. We will refactor things (so we can write non-hacky tests, use Mocks and possibly even get rid of the Singletons), but first we need test coverage...
As said before, we have a significant number of "Singleton" type classes in our project, i.e. something along the lines of.
class SomeSingleton
{
public:
static SomeSingleton& getSingleton()
{
if (m_singletonInstance == nullptr)
m_singletonInstance = new SomeSingleton();
return *m_singletonInstance;
}
protected:
SomeSingleton();
virtual ~SomeSingleton();
static SomeSingleton* m_singletonInstance = nullptr;
}
In order to properly run our unit tests the Singleton needs to be "reset" (or data from our previous tests may persist in the singleton, influencing the current test). Unfortunately there is no feasible way to do that (the Singleton instance and the destructor are protected).
We do not wish to change our production code to contain test-only functionality (i.e. no forward declaring a ::test::SomeSingletonResetter as a friend in SomeSingleton, no introducting a public void resetSingleton_forTestUseOnly() function etc.) - and we also wish to avoid any significant changes to the production code until we have test coverage in place.
So, here's the dirty hack we are considering:
In the test project we derive a very simple wrapper class (i.e. no members) from the Singleton with a static function that deletes the singleton - however as the destructor cannot be called even from the derived class (it is protected) we would static_cast the singleton to the derived class and delete that:
class SomeSingletonWrapper : public SomeSingleton
{
public:
SomeSingletonWrapper();
~SomeSingletonWrapper() override;
static void reset()
{
//can't delete/call destructor on SomeSingleton since it is protected
delete static_cast<SomeSingletonWrapper*>(m_singletonInstance);
m_singletonInstance = nullptr;
}
}
Our thoughts are, the classes are essentially the same size, and the derive classes' destructor will call the base destructor, so the class gets destroyed properly. Can this work (until we can refactor things) or will it horribly explode in our faces? And is there a better (less hacky) way to archive this (without majorly modifying the production code)?
Edit:
I am aware that the alternative would have been to simply not call the destructor (and only set m_singletonInstance = nullptr) but that would be even worse since I now leak memory with every single test and those singletons keep floating around until the test app terminates, doing god-knows-what... brrr....
According to the standard 5.3.5.2:
In the first alternative (delete object), the value of the operand of delete may be a null pointer value, a pointer to a non-array object created by a previous new-expression, or a pointer to a subobject (1.8) representing a base class of such an object (Clause 10). If not, the behavior is undefined.
Since you are deleting a super-class, not a sub-class, and the pointer was not previously created as an instance of that super-class, you are in undefined territory. So you may get lucky and it will work sometimes on some systems with some compiler, but there is no guarantee.
Can you override getSingleton()? It's not virtual or static in the code given, but it should probably be one of those. If the former, there's an easier solution (override it in your wrapper). If not, you might consider trying to replace the created value with your wrapper:
class SomeSingletonWrapper : public SomeSingleton
{
public:
static void injectWrapper()
{
// Should be null or else someone used it before we replaced it
if( m_singletonInstance != nullptr )
{
throw std::exception( "Singleton wrapping failed!" );
}
m_singletonInstance = new SomeSingletonWrapper();
}
static void resetWrapper()
{
auto wrapper = dynamic_cast<SomeSingletonWrapper*>( m_singletonInstance );
if( wrapper == nullptr )
{
throw std::exception( "Singleton wrapping failed in the reset!" );
}
delete wrapper;
m_singletonInstance = nullptr;
}
}
Then in your test, replace it before anyone uses it (but beware the static order initialization fiasco where something else might get the old instance first):
class MyTest
{
public:
void testSetup()
{
SomeSingletonWrapper::injectWrapper();
}
void testCleanup()
{
SomeSingletonWrapper::resetWrapper();
}
void testMySingletonUse()
{
auto& single = SomeSingleton::getInstance();
ASSERT( dynamic_cast<SomeSingletonWrapper*>( &single ) ); // Yay! It worked!
// More testy stuff using 'single'
}
}

what is the exact use and implementation of singleton class?

I know the singleton class does not allow to create more than one object. but as per my below code i can create as many objects as possible.
class Singleton
{
private :
static Singleton *m_Instance;
Singleton()
{
cout<<"In defailt constructor"<<endl;
}
Singleton(int x)
{
i = x;
cout<<"in param const"<<endl;
}
public:
static int i;
static Singleton* createInstance()
{
if(!m_Instance)
m_Instance = new Singleton(20);
Singleton sing;
return m_Instance;
}
};
int Singleton::i=0;
Singleton* Singleton::m_Instance = NULL;
int main()
{
Singleton *pt = Singleton::createInstance();
return 1;
}
Here I am able to create an object in the static function (as i can access constructor within the class) then where is the concept of Single object?
This isn't a singleton for the simple reason that you deliberately wrote something that isn't a singleton.
The idea is that you write the instance function so that it will only create one instance, and write other members so that they don't create any. Then, since they're the only functions that could create any instances, there will only be one.
If you remove the dodgy Singleton sing;, then you'll have a singleton implementation - only one instance will be created, the first time someone calls the function.
As with all attempts to implement this anti-pattern in C++, there are problems: the object is never destroyed, and the initialisation isn't thread-safe. There are various other approaches, each with their own drawbacks. I suggest you avoid global variables altogether, whether or not you dress them up as singletons or other anti-patterns.
The concept of single object comes when in your code, every time you need an instance of your Object, instead of using:
Singleton *myOwnSingleton= new Singleton(20);
You should always use:
Singleton *pt = Singleton::createInstance();
As the constructor is inaccesible outside of the class, the only way to create a Singleton is by Singleton::createInstance(), and if you read the code, only the first time that we call Singleton::createInstance() a new instance is created.
All subsequent calls to this method will return the already created object. So in all your execution you will only have one instance created.
But of course... you should delete the line
Singleton sing;
because it is a wrong utilization of Singleton. If you create a class called CAR but without wheels... it is not a car. And you make a class called singleton, but... with two objects of the same type. It's not beauty!

What exactly does getinstance() do in a singleton?

I have come across the singleton pattern.
I was unable to understand the difference between
singletonobj.getinstance().dosomething() //1st one
and
singletonobj.dosomething() //2nd one
What does getinstance() do, that isn’t being done in the second case?
Well, technically, singletonobj.getinstance() is redundant, because that means you already got a hold of the object.
The call would usually look something like:
SingletonClass::getinstance().dosomething();
or
singletonobj.dosomething()
in case you pre-fetched the object - i.e. previously did
SingletonClass& singletonobj = SingletonClass::getinstance();
First, singletonobj is a wrong/confusing name. Singletons are called on a class basis, like:
Log::getInstance().doSomething();
and not
Log log = new Log;
log.getInstance().doSomething();
So this should answer the question, but I'll detail anyway :)
Log::doSomething();
would force doSomething() to be a static method, while
Log::getInstance().doSomething();
has doSomething() as an instance method.
Why use getInstance()? Because a singleton, by its very definition, should only have zero or one instances. By making the constructor for a singleton private and publishing the getInstance() method, it allows you to control how many instances of this class there are. The private constructor is simply to avoid other classes to instance this class, which would defeat the purpose of this class being a singleton, as you wouldn't be able to control how many instances of this class there are.
class SingletonExample {
private:
static SingletonExample* instance = NULL;
SingletonExample() { }
public:
static SingletonExample getInstance() {
if (instance == NULL) {
instance = new SingletonExample;
}
return *instance;
}
void doSomething() {
// Do something :)
}
}
It would appear that that the first example is calling a regular method, whereas the second example is calling a static method.
The Singleton design pattern ensures that only a single instance of a given object is instantiated at any given time. The first example returns said instance, and then calls a method using an instance of an object.
The second example appears to be using a static method that does not require an instance of an object and actually invalidates the singleton design pattern...

Why cant we create Object if constructor is in private section?

I want to know why cant we create object if the constructor is in private section. I know that if i make a method static i can call that method using
<classname> :: <methodname(...)>;
But why can't we create object is what I don't understand.
I also know if my method is not static then also I can call function by the following:
class A
{
A();
public:
void fun1();
void fun2();
void fun3();
};
int main()
{
A *obj =(A*)malloc(sizeof(A));
//Here we can't use new A() because constructor is in private
//but we can use malloc with it, but it will not call the constructor
//and hence it is harmful because object may not be in usable state.
obj->fun1();
obj->fun2();
obj->fun3();
}
So, my question is: why can't we create an object when constructor is private?
Because it is not accessible to the program, that's what private means. If you declared a member function or variable private, you would not be able to access them either. Creating private constructors is actually a useful technique in C++, as it allows you to say that only specific classes can create instances of the type. For example:
class A {
A() {} // private ctor
friend class B;
};
class B {
public:
A * MakeA() {
return new A;
}
};
Only B can create A objects - this is useful when implementing the factory pattern.
A constructor is a special member function. It obeys the same rules as any other method when it comes to accessing it. The private access label prevents class users from invoking/accessing members declared under it.
The "new" operator needs to call the constructor, so if the constructor is private you can not execute the code "obj = new A" except inside member functions of the class A itself.
I would guess that what you have encountered is a technique that is very often used in Java (and yes I know you're writing C++, but the principle is the same) where the designer of the class wants to make sure that one and only one instance of this class will ever exist (which is called a "singleton"). To achieve this, he needs to prevent other code from creating further instances of the class using new, and making the constructor private is one way to do that. Here's a piece of Java code illustrating the technique.
public class MySingleton {
private MySingleton() {
// Private constructor, to prevent instantiation using "new"
// outside of this class.
}
public synchronized static MySingleton getInstance() {
static MySingleton instance = null;
if (instance == null) {
// I can use new here because I'm inside the class.
instance = new MySingleton();
}
return instance;
}
}
Even if you don't know Java, the syntax is similar enough to C++ that you should understand what this code is doing. The point is that the only way to get a reference to an instance of the MySingleton class elsewhere in the code is to call the static class member getInstance().
MySingleton obj = MySingleton.getInstance();
You can't instantiate your class because the constructor is private. private member variables and functions cannot be used outside of the class itself.
If you want to be able to instantiate your class, you have two options.
Option 1 is to make the constructor. This is the Right Thing to do in the vast majority of cases. Making a constructor private is a useful technique, but only when trying to accomplish specific goals.
Option 2 is to create a public static factory method. You would typically do this when Option 1 isn't an option.
class A
{
A();
public:
static A* Create() { return new A; }
void fun1();
void fun2();
void fun3();
};
int main()
{
A *obj = A::Create();
//Here we can't use new A() because constructor is in private
//but we can use malloc with it, but it will not call the constructor
//and hence it is harmful because object may not be in usable state.
obj->fun1();
obj->fun2();
obj->fun3();
}

Factory method pattern implementation in C++: scoping, and pointer versus reference

I've been looking at the example C++ Factory method pattern at Wikipedia and have a couple of questions:
Since the factory method is static, does that mean the newly created object won't go out of scope and have the destructor method called when the factory method exits?
Why return a pointer, as opposed to a reference? Is it strictly a matter of preference, or is the some important reason for this?
Edit 1: The more I think about it, both the reference and the pointer returned will stay in scope because they are referenced outside of the method. Therefore, the destructor won't be called on either one. So it's a matter of preference. No?
Edit 2: I printed out the destructor call on the returned reference, and it doesn't print until the program exits. So, barring further feedback, I'm going to go with the reference for now. Just so I can use the "." operator on the returned object.
Static method is one that can be called without having an instance of the factory. That has nothing to deal wtih the lifetime of the newly created object. You could use a non-static method with the same success. The factory method usually doesn't need any data from an existing object of the same class and therefor doesn't need an existing instance and this is why factorey methods are usually static.
You will use new to create the object that the factory will return. It's usual to return them by pointer. This shows explicitly that it's a new object ant the caller must take care of its lifetime.
I'm thinking there is a greater issue of understanding memory management. The factory method is allocating items on the heap (using new). Items on the heap never get automatically reclaimed (except by modern desktop OSs on process termination). The behavior you are describing is for items on the stack where they are reclaimed when you leave the local scope.
If you return a reference to an object that reference will become invalid when the method goes out of scope. This won't happen with a pointer, since the destructor isn't called.
It is true that static modifies when the value goes out of scope, but only if the variable is declared static, not if the method is declared static.
Your Wiki link says wrong.
There shouldn't be any static method. You can consider Factory Method as Template Method pattern that creates Objects. This method doesn't receive any "Name" parameter and create all the time same type of object.
Often, designs start out using Factory
Method (less complicated, more
customizable, subclasses proliferate)
and evolve toward Abstract Factory,
Prototype, or Builder (more flexible,
more complex) as the designer
discovers where more flexibility is
needed. [GoF, p136]
In the following example Business::makeObject is the factory method
class ObjectBase
{
public:
virtual void action() = 0;
virtual ~ObjectBase(){};
};
class ObjectFirst : public ObjectBase
{
public:
virtual void action(){ std::cout << "First"; }
};
class ObjectSecond : public ObjectBase
{
public:
virtual void action(){ std::cout << "Second"; }
};
class Business
{
public:
void SendReport()
{
std::auto_ptr< ObjectBase > object(makeObject());
object->action();
}
virtual ~Business() { }
protected:
virtual ObjectBase* makeObject() = 0;
};
class BusinessOne: public Business
{
public:
protected:
virtual ObjectBase* makeObject()
{
return new ObjectFirst();
}
};
class BusinessTwo: public Business
{
public:
protected:
virtual ObjectBase* makeObject()
{
return new ObjectSecond();
}
};
int main()
{
std::auto_ptr<Business> business( new BusinessTwo() );
business->SendReport();
return 0;
}
No. Static method - is almost same as global function in class namesapce and with access to private static variables;
Pointers usage is issue of createing objects in heap. They create object in heap for longer object lifetime than create-function scope;
EDIT:
I think wikipedia - is wrong in c++ example.
We have in exmaple - not same implementation as in class diagram or here (http://www.apwebco.com/gofpatterns/creational/FactoryMethod.html)
It will be better if you read about patterns from most trusted sources, e.g: Design Patterns: Elements of Reusable Object-Oriented Software.
The keyword static means different things on a method and on a variable. On a method as in the example it means that it is class global, and you need not have an instance of the class to call it.
To create a new object dynamically you need to use new, or 'a trick' is to assign a temporary object to a reference. assigning a temporary object to a point will not keep that object alive.
So you could do the following, but it is not normally done because you would often want to keep many things created from a factory, and then you would have to copy them rather than simply holding the pointer in a list.
class PizzaFactory {
public:
static Pizza& create_pizza(const std::string& type) {
if (type == "Ham and Mushroom")
return HamAndMushroomPizza();
else if (type == "Hawaiian")
return HawaiianPizza();
else
return DeluxePizza();
}
};
const Pizza &one = create_pizza(""); // by ref
Pizza two = create_pizza(""); // copied
EDIT
Sorry mistake in code - added missing const to ref.
Normally, a temporary object lasts only until the end of the full expression in which it appears. However, C++ deliberately specifies that binding a temporary object to a reference to const on the stack lengthens the lifetime of the temporary to the lifetime of the reference itself