According to John C. Mitchell - Concepts in programming languages,
[...] Java guarantees that a constructor is called whenever an object is created.
If your class defines at least one constructor, then the language will not allow you to construct an object of that type without calling a constructor.
If your class does not define a constructor, then the general rule is that the compiler-generated default constructor will be called.
As other posters have mentioned, if your class is a POD type, there are cases where your object will be left uninitialized. But this is not because the compiler "didn't call the constructor". It is because the type has no constructor (or it has one which does nothing), and is handled somewhat specially. But then again, POD types don't exist in Java, so that can't really be compared.
You can also hack around things so that the constructor is not called. For example, allocate a buffer of char
's, take a pointer to the first char and cast it to the object type. Undefined behavior in most cases, of course, so it's not really "allowed", but the compiler generally won't complain.
But the bottom line is that any book which makes claims like these without being very explicit about which specific corner cases they're referring to, is most likely full of garbage. Then again, most people writing about C++ don't actually know much about the language, so it shouldn't be a surprise.
Java can actually allocate objects without(!) calling any constructor.
If you browse the sources of ObjectInputStream
you will find that it allocates the deserialized objects without calling any constructor.
The method which allows you to do so is not part of the public API, it is in a sun.*
package. However, please don't tell me it is not part of the language because of that. What you can do with public API is put together the byte stream of a deserialized object, read it in and there you go with an instance of the object whose constructor was never called!
What he means is in Java, constructor of the super class is always called. This is done by calling super(...), and if you omit this compiler will insert one for you. Only exception is one constructor calls another constructor. In that case other constructor should call super(...).
This automatic code insertion by the compiler is strange actually. And if you do not have super(...) call, and the parent class does not have a constructor with no parameter it will result in a compile error. (It is odd to have a compile error for something that is automatically inserted.)
C++ will not do this automatic insertion for you.
Trying to make things clear about C++. Lots of imprecise statements in answers.
In C++, a POD and a class behave the same way. A constructor is ALWAYS called. For POD, the default constructor does nothing: it does not initializes the value. But it is an error to say that no constructor is called.
Even with inheritance, constructors are called.
class A {
public: A() {}
};
class B: public A {
public: B() {} // Even if not explicitely stated, class A constructor WILL be called!
};
For C++ types that declare constructors, it is not possible to create instances of those types without the use of a constructor. For example:
class A {
public:
A( int x ) : n( x ) {}
private:
int n;
};
it is not posible to create instancev of A without using the A(int) constructor, except by copying, which in this instance will use the synthesised copy constructor. In either case, a constructor must be used.
even in the case we use statically allocated memory buffer for object creation , constructor is called.
can be seen in the following code snippet. i haven't seen any general case yet where constructor is not called, but then there is so much to be seen :)
using namespace std;
class Object
{
public:
Object();
~Object();
};
inline Object::Object()
{
cout << "Constructor\n";
};
inline Object::~Object()
{
cout << "Destructor\n";
};
int main()
{
char buffer[2 * sizeof(Object)];
Object *obj = new(buffer) Object; // placement new, 1st object
new(buffer + sizeof(Object)) Object; // placement new, 2nd object
// delete obj; // DON’T DO THIS
obj[0].~Object(); // destroy 1st object
obj[1].~Object(); // destroy 2nd object
}