Calling constructors in c++ without new
Both lines are in fact correct but do subtly different things.
The first line creates a new object on the stack by calling a constructor of the format Thing(const char*)
.
The second one is a bit more complex. It essentially does the following
- Create an object of type
Thing
using the constructorThing(const char*)
- Create an object of type
Thing
using the constructorThing(const Thing&)
- Call
~Thing()
on the object created in step #1
C++, is it possible to call a constructor directly, without new?
Sort of. You can use placement new to run the constructor using already-allocated memory:
#include <new>
Object1 ooo[2] = {Object1("I'm the first object"), Object1("I'm the 2nd")};
do_smth_useful(ooo);
ooo[0].~Object1(); // call destructor
new (&ooo[0]) Object1("I'm the 3rd object in place of first");
So, you're still using the new
keyword, but no memory allocation takes place.
Can constructor call another constructor in c++?
Not before C++11.
Extract the common functionality into a separate function instead. I usually name this function construct().
The "so-called" second call would compile, but has a different meaning in C++: it would construct a new object, a temporary, which will then be instantly deleted at the end of the statement. So, no.
A destructor, however, can be called without a problem.
How to call constructor without new?
You can use cast operator to implicitly:
sealed class Student
{
public string Name
{
get;
private set;
}
Student()
{
}
public static implicit operator Student(string name)
{
return new Student
{
Name = name
};
}
}
Then you can do Student student = "Sabrina";
.
C++: allocate block of T without calling constructor
Firstly, you are not allocating a "block of T*
". You are allocating a "block of T
".
Secondly, if your T
has non-trivial constructor, then until elements are constructed, your block is not really a "block of T", but rather a block of raw memory. There's no point in involving T
here at all (except for calculating size). A void *
pointer is more appropriate with raw memory.
To allocate the memory you can use whatever you prefer
void *raw_data = malloc(num * sizeof(T));
or
void *raw_data = new unsigned char[num * sizeof(T)];
or
void *raw_data = ::operator new(num * sizeof(T));
or
std::allocator<T> a;
void *raw_data = a.allocate(num);
// or
// T *raw_data = a.allocate(num);
Later, when you actually construct the elements (using placement new, as you said), you'll finally get a meaningful pointer of type T *
, but as long as the memory is raw, using T *
makes little sense (although it is not an error).
Unless your T
has some exotic alignment requirements, the memory returned by the above allocation functions will be properly aligned.
You might actually want to take a look at the memory utilities provided by C++ standard library: std::allocator<>
with allocate
and construct
methods, and algorithms as uninitialized_fill
etc. instead or trying to reinvent the wheel.
Call to constructors without the new keyword
Without copying the exact line that worries you I might be off target, but if your concern is code like:
T f() {
return T();
}
That is not a call to the constructor, but rather the creation of a temporary which in this case is value-initialized. The memory is allocated locally in the stack (if at all, Return Value Optimization should avoid it).
Constructor without new C#
You can implement it like this:
public class Person {
// Private (or protected) Constructor to ensure using factory methods
private Person(String name) {
if (null == name)
name = "SomeDefaultValue";
//TODO: put relevant code here
}
// Factory method, please notice "static"
public static Person CreateWithName(String name) {
return new Person(name);
}
// Factory method, please notice "static"
public static Person CreateEmpty() {
return new Person(null);
}
}
Does the `new` operator always call the constructor?
If you search for constructor
on the linked MSDN page, it says this:
When
new
is used to allocate memory for a C++ class object, the object's constructor is called after the memory is allocated.
In other words, a constructor is called if one exists. If none exists, none is called.
Instantiating objects without calling the constructor in C++
5 is an example of C++'s most vexing parse.
Dog dog();
This declares a function named dog
that accepts no parameters and returns a Dog
. To avoid the most vexing parse (and if you are using C++11), you can do:
Dog dog{};
And semantically (at least until C++17), Dog dog = Dog();
will first create a temporary object (Dog()
), and then move construct (or copy construct, if Dog
class has no move constructor) a named object (dog
) from it. Although compilers might optimize the move away, this statement does have different semantics from the rest.
If I remember correctly, since C++17, P0135r0 will change the semantics of Dog dog = Dog();
so that it has the same meaning as Dog dog;
.
EDIT: As pointed out by @LightnessRacesinOrbit in the comments, Dog dog();
is vexing, but not quite the most vexing parse. Dog dog(Dog());
is true most vexing parse. Dog dog();
is just a, well, plain declaration, I guess.
Related Topics
How to Typedef a Type and the Same Type's Pointer
The Difference Between C and C++ Regarding the ++ Operator
How Does Std::Vector Support Contiguous Memory for Custom Objects of Unknown Size
What Are the Stages of Compilation of a C++ Program
Vector.Erase(Iterator) Causes Bad Memory Access
Passing Std::String by Value or Reference
Is There Any 'Out-Of-The-Box' 2D/3D Plotting Library for C++
Check Char at Current/Given Position in Pdcurses/Ncurses
How to Send Keystrokes to a Window
Why It Is Different Between -2147483648 and (Int)-2147483648
How to Make My Program in Qt Continually Send a String to My Arduino
How to Create a Http Mjpeg Streaming Server with Qtcp-Server Sockets
Why Vector.Size()-1 Gives Garbage Value