I can't find the answer anywhere. It can be done by using condition and throwing exception but is there any other way to do so?
It isn't clear why you would want a class that cannot be constructed under any circumstances, but you could make all constructors private and provide no implementation for them. This will prevent construction at compile time.
In C++11 you can use delete for all the constructors:
class A
{
public: // or private, doesn't matter.
A()=delete;
A(const A&)=delete;
A(A&&)=delete;
};
Well, this is a bit of an awful hack but quite frankly any C++ application which needs a way to define an unconstructable object is probably already an awful hack!
class la
{
public:
virtual void oh_no_you_dont() = 0;
};
int main()
{
la an_instance;
return 0;
}
And under GCC, I get the following:
test.cpp: In function ‘int main()’:
test.cpp:9: error: cannot declare variable ‘an_instance’ to be of abstract type ‘la’
test.cpp:2: note: because the following virtual functions are pure within ‘la’:
test.cpp:4: note: virtual void la::oh_no_you_dont()
You can make all constructors private. This way it's impossible to create an instance of the class. You can then supply one or more static factory methods for creating the class, and by this make the users use only factory methods.
Do you want your class to prevent from being constructed?
Here is a solution with an old C++ standard e.g. C++03 and older
class A {
private:
A();
A(const A&)
A(A&&);
~A()
};
Here is a solution using the latest C++ standard e.g. C++11, C++14, C++17, C++20
class A
{
A()=delete;
A(const A&)=delete;
A(A&&)=delete;
};
or even
class A final {
~A() = delete;
}
final means that a class cannot be inherited from.
delete for a destructor means that you can not destruct a class
Prohibiting a destructor blocks you from constructing an object also.
Why do we want to prohibit objects from being constructed/destructed?
A very common use case is that a developer wants to create a "static" class in C++.
"static" class in C++ means a class with only static methods.
This pattern is also know as an "util" class.
Instead of defining a class many people advice to use a canonical namespace that contains static functions for this purpose.
Related
Is there a way in C++ to forbid code to compile if the specific function was not called.
Imagine I have some class:
class CExample
{
public:
void Init();
void DoWork();
};
Is there a way to forbid calling DoWork() if the Init() function was not called for class object?
I want to forbid writing such a code:
CExample e;
e.DoWork();
and permit this version:
CExample e;
e.Init();
e.DoWork();
Can I reach this behaviour somehow with metaprogramming?
You can just use a constructor instead of Init.
In his notes about exception safety in the standard library, as appendix to the 3rd edition of The C++ Programming Language, Bjarne Stroustrup discussed how using init functions is at odds with the notion of class invariant. It's generally Bad Practice™, mainly for that reason.
Some old GUI frameworks like Microsoft's MFC used init functions in order to do derived class specific initialization. There are other techniques to do that, including just passing the required information up the construction chain via arguments.
No, that would be bad design. If it must be called for the object to be usable, it should be called in the constructor. After an object is constructed, all public methods should be callable-- the object should be fully constructed and ready for use.
At compile time it is not known if Init() has been called before DoWork(). This can only be decided at runtime. Therefore metaprogramming will not be useful here.
You should put your init code into the constructor to enforce that the class is properly constructed. However if you really insist, and your init function really isn't polymorphic you can use CRTP with a protected constructor:
template <typename What>
class InitMe : public What
{
public:
InitMe() : What() { this->Init(); }
};
class CExample
{
public:
void Init() {}
void DoWork() {}
protected:
CExample() {}
};
int main()
{
//CExample e; // Error: protected constructor.
InitMe<CExample> e;
e.DoWork();
}
As Cheers and hth. -Alf and Rob K have both touched on, you most definitely want to have your init work performed in your class constructor. Having to call a separate function to ensure your class is properly ready is poor design.
However, that being said, you can detect if it's been called and act accordingly anyway:
void CExample::Init()
{
// things
...
init = true;
}
void CExample::DoWork()
{
if (!init)
{
Init();
}
}
I can understand defaulted constructors, since user defined constructors will disable the compiler generated ones making the object non trivially copyable etc.
In the destructor case, apart from changing access category, what use is there to define a defaulted destructor considering that no user defined member function can disable them (you can't overload destructors anyway) ?
// Which version should I choose ?
struct Example
{
//1. ~Example() = default;
//2. ~Example() {}
//3.
};
Even in the case of virtual destructors, defaulting them would not make them trivial so what good is it doing it?
The exception for trivial destructors omission has to do with the derived class' destructor, not the base one. So virtual ~Foo() = default; is a useful construct to keep the default destructor, but virtualize it.
One use is making the destructor protected or private while potentially keeping the class trivial: just list it after the desired access specifier.
Another: when writing classes, some programmers like to order the class's functions: e.g. constructors, then the destructor, then the non-const "mutating" members, then the const "accessor" members, then static functions. By being able to explicitly = default the destructor, you can list it in the expected order and the reader looking there knows there can't be another misplaced version of it. In large classes, that may have some documentary/safety value.
It also gives you something concrete around which to add comments, which can help some documentation tools realise the comments relate to destruction.
Basically it is about communicating the intent, but pretty redundant.
But in case you're using std::unique_ptr as a member of class you'll need to declare destructor (but only declare) in header. Then you can make it use default implementation in source file like so:
MyClass:~MyClass() = default;
Considering your options I would use first or third one.
As mentioned by Nikos Athanasiou in a comment, a default constructor makes the type trivially destructible, where a user defined one does not. A little code sample will show it:
#include <iostream>
#include <type_traits>
struct A { ~A() = default; };
struct B { ~B() {} };
struct C { ~C() noexcept {} };
int main() {
std::cout
<< std::is_trivially_destructible<A>::value
<< std::is_trivially_destructible<B>::value
<< std::is_trivially_destructible<C>::value
<< std::endl;
return 0;
}
Displays
100
As for virtual destructors, consistency with non-virtual ones and Quentin's answer are appropriate reasons. My personal advice is that you should always use the default when you can, as this is a way to stick to the most canonic behavior.
In C++ (since C++ 11 I believe), it is possible to "delete" constructors, or assignment operators, whenever the programmer does not want the compiler to automatically implement a default constructor, or assignment operator.
For example, one may,
class a
{
const a& operator=(const a& copy_me) = delete;
}
which will remove the default assignment operator. The compiler will not implement a default operator= for us. We simply will not be able to us it in our code, it will be as if it was never there.
Consider an abstract base class (or just a base class) with functions, virtual functions and pure virtuals.
class example_base
{
void function()
{
return;
}
virtual
void virtual_function() // Do we have to provide an implementation?
{
return;
}
virtual
void pure() = 0; // Are there other ways to declare a pure virtual?
// Can pure() have an implementation in this class?
}
If another class inherits from the base class, are we allowed to "delete" some of the functions provided in the base? (Q1)
If so, what are the rules and effects of this? (Q2)
What will happen if a subsequent class inherits from example_inherits and we have deleted some of the member functions? Are we allowed to use them again? (Q3)
class example_inherits : example_base
{
void function() = delete; // Allowed?
virtual
void virtual_function() = delete; // If so why ...
virtual
void pure() = delete; // ... or why not?
}
Example of Q3:
class another : example_inherits
{
// Allowed to use deleted function?
void function()
{
std::cout << "blaa" << std::endl;
}
}
You can probably think of other permutations of what I described, such as implementing a deleted method 2 orders of inheritance lower. (ie, in a class which inherits from a class which inherits from a class...)
Or different choices of virtual / pure virtual orderings... eg: one class has a virtual pure, something inherits from this class and inherits the same function as a virtual, then another class which inherits from this either deletes it or implements it as a regular function... etc...
Some insight into this would be appreciated - I wasn't able to find information this detailed online.
Well, you have quite a lot of questions here. And they all could have been answered by trying it :)
We simply will not be able to us it in our code, it will be as if it was never there
Not quite, because the deleted version participates in overload resolution. For example:
void f(long);
void f(int) = delete;
f(5);
This will fail to compile, however if you comment out the =delete version then it compiles.
Moving onto your questions.
Can pure() have an implementation in this class?
Yes, = 0 only means that derived classes must override it. But you can still provide an out-of-line definition for that function in the same class.
void function() = delete; // Allowed?
Yes, this is allowed. The derived function() hides the base function(), since it is not virtual. You could of course still call the base function through a pointer or reference to the base class.
void virtual_function() = delete;
This is not allowed; virtual functions may not be deleted.
Matt's answer covers almost everything, but I can answer the question on why you cannot delete virtual functions (Q3):
The entire point of virtual functions is to enable subtype polymorphism. A sane implementation of this implies that you can use any legally implemented subtype in any legally implemented function that is written using the base type. This is a rephrasing of the Liskov Substitution Principle.
This means if you were able to delete a virtual function in a subclass, this subclass would create undefined behavior when used in a legally implemented function. Not exactly desirable, and I can't imagine a situation where it would give any benefit either.
Is it good practice to make a base class constructor protected if I want to avoid instances of it? I know that I could as well have a pure virtual dummy method, but that seems odd...
Please consider the following code:
#include <iostream>
using std::cout;
using std::endl;
class A
{
protected:
A(){};
public:
virtual void foo(){cout << "A\n";};
};
class B : public A
{
public:
void foo(){cout << "B\n";}
};
int main()
{
B b;
b.foo();
A *pa = new B;
pa->foo();
// this does (and should) not compile:
//A a;
//a.foo();
return 0;
}
Is there a disadvantage or side-effect, that I don't see?
It is common practice to make base class constructors protected. When you have a pure-virtual function in your base class, this is not required, as you wouldn't be able to instantiate it.
However, defining a non-pure virtual function in a base class is not considered good practice, but heavily depends on your use case and does not harm.
There isn't any disadvantage or side-effect. With a protected constructor you just tell other developers that your class is only intended to be used as a base.
What you want to achieve is normally done via the destructor, instead of the constructors, just beacause you can steer the behavior you need with that one function instead of having to deal with it with every new constructor you write. It's a common coding style/guideline, to
make the destructor public, if you want to allow instances of the class. Often those classes are not meant to be inherited from.
make the destructor pure virtual and public, if you want to use and delete the class in a polymorphic context but don't want to allow instances of the class. In other words, for base classes that are deleted polymorphcally.
make the destructor nonvirtual and protected, if you don't want to allow instances of the class and don't want to delete its derivates polymorphically. Normally, you then don't want to use them polymorphically at all, i.e. they have no virtual functions.
Which of the latter two you chose is a design decision and cannot be answered from your question.
It does what you're asking.
However I'm not sure what you are gaining with it. Someone could just write
struct B : A {
// Just to workaround limitation imposed by A's author
};
Normally it's not that one adds nonsense pure-virtual functions to the base class... it's that there are pure virtual functions for which no meaningful implementation can be provided at the base level and that's why they end up being pure virtual.
Not being able to instantiate that class comes as a nice extra property.
Make the destructor pure virtual. Every class has a destructor, and a base class should usually have a virtual destructor, so you are not adding a useless dummy function.
Take note that a pure virtual destructor must have a function body.
class AbstractBase
{
public:
virtual ~AbstractBase() = 0;
};
inline AbstractBase::~AbstractBase() {}
If you don't wish to put the destructor body in the header file, put it in the source file and remove inline keyword.
I was wondering if there is a way to declare an object in c++ to prevent it from being subclassed. Is there an equivalent to declaring a final object in Java?
From C++ FAQ, section on inheritance
This is known as making the class
"final" or "a leaf." There are three
ways to do it: an easy technical
approach, an even easier non-technical
approach, and a slightly trickier
technical approach.
The (easy) technical approach is to
make the class's constructors private
and to use the Named Constructor Idiom
to create the objects. No one can
create objects of a derived class
since the base class's constructor
will be inaccessible. The "named
constructors" themselves could return
by pointer if you want your objects
allocated by new or they could return
by value if you want the objects
created on the stack.
The (even easier) non-technical
approach is to put a big fat ugly
comment next to the class definition.
The comment could say, for example, //
We'll fire you if you inherit from
this class or even just /*final*/
class Whatever {...};. Some
programmers balk at this because it is
enforced by people rather than by
technology, but don't knock it on face
value: it is quite effective in
practice.
A slightly trickier technical approach
is to exploit virtual inheritance.
Since the most derived class's ctor
needs to directly call the virtual
base class's ctor, the following
guarantees that no concrete class can
inherit from class Fred:
class Fred;
class FredBase {
private:
friend class Fred;
FredBase() { }
};
class Fred : private virtual FredBase {
public:
...
};
Class Fred can access FredBase's ctor,
since Fred is a friend of FredBase,
but no class derived from Fred can
access FredBase's ctor, and therefore
no one can create a concrete class
derived from Fred.
If you are in extremely
space-constrained environments (such
as an embedded system or a handheld
with limited memory, etc.), you should
be aware that the above technique
might add a word of memory to
sizeof(Fred). That's because most
compilers implement virtual
inheritance by adding a pointer in
objects of the derived class. This is
compiler specific; your mileage may
vary.
No, there isn't really a need to. If your class doesn't have a virtual destructor it isn't safe to derive from it anyway. So don't give it one.
You can use this trick, copied from Stroustrup's FAQ:
class Usable;
class Usable_lock {
friend class Usable;
private:
Usable_lock() {}
Usable_lock(const Usable_lock&) {}
};
class Usable : public virtual Usable_lock {
// ...
public:
Usable();
Usable(char*);
// ...
};
Usable a;
class DD : public Usable { };
DD dd; // error: DD::DD() cannot access
// Usable_lock::Usable_lock(): private member
In C++0x (and as an extension, in MSVC) you can actually make it pretty clean:
template <typename T>
class final
{
private:
friend T; // C++0x, MSVC extension
final() {}
final(const final&) {}
};
class no_derived :
public virtual final<no_derived> // ah, reusable
{};
NO.
The closest you can come is to declare the constructors private, then provide a static factory method.
There is no direct equivalent language construct for this in C++.
The usual idiom to achieve this technically is to declare its constructor(s) private. To instantiate such a class, you need to define a public static factory method then.
As of C++11, you can add the final keyword to your class, eg
class CBase final
{
...
The main reason I can see for wanting to do this (and the reason I came looking for this question) is to mark a class as non subclassable so you can safely use a non-virtual destructor and avoid a vtable altogether.
There is no way really. The best you can do is make all your member functions non-virtual and all your member variables private so there is no advantage to be had from subclassing the class.