Explicitly calling constructors

P

Prasoon

Can constructors be explicitly called in a program without using
placement new???

As far as I know....considering the code snippet

#include<iostream>

class demo
{
public:

demo(){
std::cout<<"Constructor invoked";
}

~demo(){
std::cout<<"Destructor invoked";
}
};

int main()
{
demo d;//Constructor invoked
d.demo();//Compilation error

demo();//Creation of nameless object
d.~demo();//Allowed but may lead to undefined behaviour as the
local object
//d can be destructed twice

}

Is the creation of nameless object in the above code an explicit call
to constructor or not???

According to me,its not. To call a constructor explicitly we need to
use Placement new but again it is not recommended to use "Placement
New"

Is there any other way of calling constructors explicitly????

P.S: Not to confuse with the explicit keyword

Prasoon
 
N

Neelesh

Can constructors be explicitly called in a program without using
placement new???
Of course yes.

Foo *f = new Foo(); //Foo::Foo() called explicitly
Foo *f2 = new Foo(1,2); //Foo::Foo(int,int) called explicitly

Creation of an object is a two step process- (a) memory allocation,
and (b) Converting the raw memory into a valid "object". Constructors
are responsible for the second step, and "placement new" differs from
"new" as far as the only first step is concerned. The second step
(i.e. the constructor call) is common for both. IOW Placement new is
about "memory allocation" part of object creation process, and not
about the "construction of object from the raw memory".
As far as I know....considering the code snippet

#include<iostream>

class demo
{
    public:

    demo(){
          std::cout<<"Constructor invoked";
    }

   ~demo(){
          std::cout<<"Destructor invoked";
    }
 };

int main()
{
     demo d;//Constructor invoked
     d.demo();//Compilation error

There is a compilation error above because constructors donot have
names. Hence, the so called member-function-call-like-syntax that has
the same name as the class doesnot call a constructor.
     demo();//Creation of nameless object
     d.~demo();//Allowed but may lead to undefined behaviour as the
local object
                        //d can be destructed twice

}

Is the creation of nameless object in the above code an explicit call
to constructor or not???
It actually depends on what is exactly meant by "explicit call to
constructor". Assuming that demo class had an extra constructor, say
demo(int), both of the following would qualify for "explicit call" to
constructor:

demo();
demo(4);

The reason I am saying these are explicit calls is that you are
"explicitly" telling the compiler which constructor is to be called.
According to me,its not. To call a constructor explicitly we need to
use Placement new but again it is not recommended to use "Placement
New"

IMHO, what is *actually* recommended is "not to use placement new
unless you have to". And that "unless you have to" clause indicates
that you are the best judge of whether it should be used in your
specific situation. http://www.parashift.com/c++-faq-lite/dtors.html#faq-11..10
Is there any other way of calling constructors explicitly????

Here is one example:

struct Foo {
explicit Foo(int s) { } //Explicit conversion constructor
};

const Foo& f = 5; //Error since Foo::Foo(int) is explicit
const Foo& f2 = Foo(5); //Ok, Constructor called explicitly, of course
not to be confused with "explicit" keyword.

Again, do you call this an explicit call to constructor?

I think that throughout this discussion, by "explicit call to
constructor" you mean that a constructor call without the first step,
i.e. memory allocation step. If that is what you mean, then placement
new is (AFAIK) the only way.
 
R

Rolf Magnus

Prasoon said:
Can constructors be explicitly called in a program without using
placement new???

No. A constructor is always implicitly invoked as part of object creation.
As far as I know....considering the code snippet

#include<iostream>

class demo
{
public:

demo(){
std::cout<<"Constructor invoked";
}

~demo(){
std::cout<<"Destructor invoked";
}
};

int main()
{
demo d;//Constructor invoked


d.demo();//Compilation error

demo();//Creation of nameless object
d.~demo();//Allowed but may lead to undefined behaviour as the
local object
//d can be destructed twice

}

Is the creation of nameless object in the above code an explicit call
to constructor or not???
According to me,its not. To call a constructor explicitly we need to
use Placement new

I wouldn't call that "call a constructor explicitly", but I know what you
mean.
but again it is not recommended to use "Placement New"

It isn't? Says who?
Is there any other way of calling constructors explicitly????

I would recommend placement new if that does what you need.
 
A

Alf P. Steinbach

* Rolf Magnus:

Jeez.

I guess it's time for the authority argument again (not thereby denigrating my
own biggie authority, but :) ):

Andrew Koenig & Bjarne Stroustrup
"The explicit constructor call greater<int>() will serve the same
purpose by creating an anonymous object:"

in

"Foundations for Native C++ Styles", section 4.1.1, <url:
http://parasol.tamu.edu/people/rwerger/Courses/434/c++primer.ps>.


A constructor is always implicitly invoked as part of object creation.

Not quite, e.g. ...

int x;

.... creates an object without calling a constructor, and so does (as I recall,
but don't flog me if the standard defines by way of a default constructor) ...

struct Foo { int x; };

int main()
{
Foo();
}

What you probably meant was that if a class has at least one declared
constructor, then, without using very low level features to circumvent this
guarantee, creating any instance of that class calls a constructor of that
class, and conversely, calling a constructor creates an instance.


Cheers & hth.,

- Alf
 
P

Prasoon

demo();//Creation of nameless object

For the above which statement is more precise???

1)Creating nameless temporary object
2)Explicitly calling constructor

Prasoon
 
A

Alf P. Steinbach

* Prasoon:
For the above which statement is more precise???

1)Creating nameless temporary object
2)Explicitly calling constructor

None of them is more precise than the other. They describe two different aspects.


Cheers & hth.,

- Alf
 
J

James Kanze

* Rolf Magnus:

[...]
Not quite, e.g. ...
... creates an object without calling a constructor, and so
does (as I recall, but don't flog me if the standard defines
by way of a default constructor) ...

I think (without actually checking) that it depends, that at
times, the standard speaks as if no constructor exists or is
called, and at times, as if there were a trivial constructor.

And while we're at it, what about "new int()"? Does that call a
(non-existant) constructor, or what?
struct Foo { int x; };
int main()
{
Foo();
}
What you probably meant was that if a class has at least one
declared constructor, then, without using very low level
features to circumvent this guarantee, creating any instance
of that class calls a constructor of that class, and
conversely, calling a constructor creates an instance.

You can't circumvent it. By definition: if an object has a
non-trivial constructor, it doesn't exist until the constructor
has run. You can, of course, obtain an lvalue expression which
has the object type but which, in fact, doesn't refer to an
object. (Which is probably what you meant by using low level
features to circumvent the guarantee, just reexpressed in
standardese.)
 
B

Bart van Ingen Schenau

Prasoon said:
For the above which statement is more precise???

1)Creating nameless temporary object
2)Explicitly calling constructor

The first statement describes more accurately what happens in the
statement.

Bart v Ingen Schenau
 
R

Rolf Magnus

Alf said:
I guess it's time for the authority argument again (not thereby
denigrating my own biggie authority, but :) ):

Andrew Koenig & Bjarne Stroustrup
"The explicit constructor call greater<int>() will serve the same
purpose by creating an anonymous object:"

Well, everyone makes an error now and then ;-)
Not quite, e.g. ...

int x;

... creates an object without calling a constructor, and so does (as I
recall, but don't flog me if the standard defines by way of a default
constructor) ...

If every constructor call is done as part of object creation, that doesn't
mean that every object creation involves a constructor call. I was rather
talking about the former, not the latter. But I admit my last posting could
be misinterpreted.
struct Foo { int x; };

int main()
{
Foo();
}

What you probably meant was that if a class has at least one declared
constructor, then, without using very low level features to circumvent
this guarantee, creating any instance of that class calls a constructor of
that class,

No. What I meant is that it's just the other way round. You cannot
circumvent it, since if the constructor hasn't been executed, it's not an
object of that type yet.
and conversely, calling a constructor creates an instance.

Also the other way round: Creating an instance leads to invocation of the
constructor.
But I believe we have been discussing this already, with neither of us being
able to convince the other.
 
A

Alf P. Steinbach

* Rolf Magnus:
Well, everyone makes an error now and then ;-)

The languages' creator, the first secretary of the committee and the standard
itself is in error about the terminology, yeah, right.

If every constructor call is done as part of object creation, that doesn't
mean that every object creation involves a constructor call. I was rather
talking about the former, not the latter. But I admit my last posting could
be misinterpreted.


No. What I meant is that it's just the other way round.

There is no "other way around": you can't have one without the other.

You cannot
circumvent it, since if the constructor hasn't been executed, it's not an
object of that type yet.

This shows that you have some fundamental misunderstanding.

It's not clear what you misunderstand but I think you should make an effort to
find out.


Cheers & hth.,

- Alf
 
R

Rolf Magnus

Alf said:
* Rolf Magnus:

The languages' creator, the first secretary of the committee and the
standard itself is in error about the terminology, yeah, right.



There is no "other way around": you can't have one without the other.



This shows that you have some fundamental misunderstanding.

It's not clear what you misunderstand but I think you should make an
effort to find out.

I guess it must be the same fundamental misunderstanding that people had
when writing paragraph 3.8 of the C++ standard:

3.8 Object Lifetime [basic.life]

1 The lifetime of an object is a runtime property of the object. The
lifetime of an object of type T begins when:

— storage with the proper alignment and size for type T is obtained, and
— if T is a class type with a non-trivial constructor (12.1), the
constructor call has completed.
 
R

Ron

I guess it must be the same fundamental misunderstanding that people had
when writing paragraph 3.8 of the C++ standard:
— storage with the proper alignment and size for type T is obtained, and
— if T is a class type with a non-trivial constructor (12.1), the
constructor call has completed.


I don't know what the problem with that. There is no doubt that the
constructor is called. The issue is whether or not you believe that
the programmer has written code that calls it. Count me in the "you
can't call constructors" crowd. You can create objects, but the
implementation calls the constructors for you as necessary. Any
syntax you think you are writing that is a constructor call, is in
fact,
a cast or temporary object creation.
 
A

Alf P. Steinbach

* Ron:
I don't know what the problem with that. There is no doubt that the
constructor is called. The issue is whether or not you believe that
the programmer has written code that calls it.

Well, It's OK, fine by me, when someone adopts the convention that a directory
is only "empty" when it contains no entries whatsoever, not even "." and "..".

It is a valid technical way of looking at it, but with unusual meanings for both
of the terms "directory" and "empty".

It can probably even help the confused person who is unable to understand that a
directory is "empty" when it contains "." and ".." (and it marks that person as
seriously confused, so anything that helps is welcome).

If I have to communicate with such a person about directories and their removal,
say, which involves considerations of whether directories are "empty", then,
after failing to convince him or her to use or even understand the usual meaning
of "empty directory", I just find some way of communicating anyway, perhaps by
agreeing on some completely new terms, some person-specific abra cadabra.

However, that person teaching his or her terminology to newbies is a problem.


Cheers & hth.,

- Alf
 
J

James Kanze

[...]
I don't know what the problem with that. There is no doubt
that the constructor is called. The issue is whether or not
you believe that the programmer has written code that calls
it.

Not even. I don't think anyone would argue that the programmer
doesn't write code which calls the constructor. The only real
issue is what is meant by "explicit" when speaking of an
"explicit constructor call". If "explicit" is meant to say: the
programmer has written an expression which intentionally and
expressedly calls the constructor, and does nothing else, I'm
sure that even Alf would agree that C++ doesn't have this.

As Alf has pointed out, of course, the same thing can be said
for calling a function, since you can't write an expression
which calls a function without also evaluating it's arguments.
And although I don't really agree with Alf here, I think he
certainly has at least a partial point: the address of the raw
memory in which the object is to be constructed is in a very
real sense a necessary argument to a constructor (if for no
other reason than the this pointer must be allocated), and any
necessary memory allocation can certainly be considered part of
evaluating that argument; there is a very real sense in which
something like "MyClass()" and "functionReturningMyClass()" are
similar, with the first calling the constructor, and the second
the function. In the end, we're not arguing about what actually
takes place in any given expression (I think Alf and Rolf agree
about that), but about how to best describe it. And we're not
helped by the fact that the standard describes it as a type
conversion, since that's a perfectly horrible way to talk about
it, given that there is nothing to convert. My preference is to
speak of "explicitly creating a temporary object", because I
think that most clearly expresses what is happening, and the
intent when I write such an expression. But Alf is certainly
not alone in calling it "explicitly calling a constructor". And
while I definitely prefer "explicitly creating an obejct",
"explicitly calling a constructor" is still better that
"explicit type conversion (functional notation)". (IMHO, of
course).

FWIW: the problem with Alf's point of view, IMHO, is that when
people ask about explicitly calling the constructor, they're
usually asking about something similar to what Java calls
"explicit constructor invocations". In C++, this would be
citing the base class in the initialization list for base
classes, but the current version of C++ doesn't have any
equivalent for the "alternate constructor invocation" of Java.
(In the next version of the standard, it will be possible for a
constructor to delegate to another constructor of the object in
the initialization list.) I have no problems with Alf using
"explicitly calling the constructor" as he does, any more than I
have problems with Stroustrup doing it (and Alf's usage does
correspond to Stroustrup's). On the other hand, when someone
asks about how to explicitly call the constructor, and they are
obviously using the phrase as it is used in Java, then the
correct answer is "you can't explicitly call the constructor in
C++". Because the context has defined "explicitly call the
constructor" in a way different from that used by Alf (or
Stroustrup). And in the way the context has defined "explicitly
call the constructor", it doesn't exist in (current) C++.
Count me in the "you can't call constructors" crowd.
You can create objects, but the implementation calls the
constructors for you as necessary. Any syntax you think you
are writing that is a constructor call, is in fact, a cast or
temporary object creation.

The problem, as I'm sure Alf would point out, is that the
standard doesn't define a syntax "temporary object creation",
any more than it defines a syntax "explicit constructor call".
And the people who start these threads aren't asking how to do
an "explicit type conversion", since they don't have anything to
convert.

All things considered: if I could find the time, I'd write up a
proposal to change the name of section §5.2.3 to "Explicit
creation of a temporary object". (It's not necessarily as
simple as it sounds. Remember that given:
struct A {} ;
struct B { operator A() ; } ;
, the expression "A( someB )" invokes B::eek:perator A(). And not
directly the constructor of A. And that with:
typedef A* APtr ;
as well, "APtr( ptrToB )" is a reinterpret_cast.)
 
Y

Yan

Can constructors be explicitly called ...

IMHO the answer depends on the definition of 'explicitly called', but
if I am guessing right what you meant by it then the answer is 'no'

Constructors (according to the Standard, Chapter 12) are 'special
member functions' and don't have names. It is my understanding that
you can't 'explicitly' or 'directly' call something that doesn't have
a name, because it's by it's name that you call it.
 
B

Bart van Ingen Schenau

Alf said:
* Rolf Magnus:

There is no "other way around": you can't have one without the other.

As far as I can see, you both are using different phrases to say the
same thing: If a type has a (non-trivial) constructor, creating an
object implies that a constructor gets invoked, and equivalently if a
constructor has been invoked, an object is being created.
This shows that you have some fundamental misunderstanding.

I don't see a misunderstanding here.
Can you show how to create an object of the non-POD type std::string
without invoking one of its constructors?
It's not clear what you misunderstand but I think you should make an
effort to find out.


Cheers & hth.,

- Alf
Bart v Ingen Schenau
 
A

Alf P. Steinbach

* Bart van Ingen Schenau:
As far as I can see, you both are using different phrases to say the
same thing: If a type has a (non-trivial) constructor, creating an
object implies that a constructor gets invoked, and equivalently if a
constructor has been invoked, an object is being created.


I don't see a misunderstanding here.

That could possibly be because you're jumping into some debate and have no idea
of the context.

Can you show how to create an object of the non-POD type std::string
without invoking one of its constructors?

First, I don't think that this has anything to do with Rolf Magnus' mixup of
levels or context or whatever his very persistent confusion is or was about.

And second, since the question is practically meaningless (see below), it may be
that you have misunderstood something, different from Rolf Magnus though.

But, if you're referring to the low-level features I mentioned, the validity of
any solution depends on the particular implementation of std::string. Such code,
reproducing a memory layout, is not portable, and is "very low-level", and since
you're asking about std::string, for which such techniques would be wholly
inappropriate no matter the context (this is why the question is practically
meaningless), my advice is to not do it, and to not even think about it.

On the other hand, in contrast to std::string and a practitioner who doesn't
know that std::string isn't relevant, it can be trivial and useful for someone
who does have the requisite understanding and who controls the class.

E.g. such techniques are used in Microsoft's libraries (not sure if they do it
for binary serialization, but e.g. downcasting for access control is, as I
recall, used in ATL).


Cheers & hth.,

- Alf
 
B

Bart van Ingen Schenau

Alf said:
* Bart van Ingen Schenau:


First, I don't think that this has anything to do with Rolf Magnus'
mixup of levels or context or whatever his very persistent confusion
is or was about.

That is possible, but you seem to be rather quick in calling people
confused, when they seem (to me) to have the same understanding as you
but phrase it differently.
And second, since the question is practically meaningless (see below),
it may be that you have misunderstood something, different from Rolf
Magnus though.

I don't think I have any misunderstanding, because you gave exactly the
answer I was expecting: it can not be done in portable code and should
not be done anyway without very special reasons.
And it probably relies on a particular form of UB.
Cheers & hth.,

- Alf

Bart v Ingen Schenau
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,961
Messages
2,570,130
Members
46,689
Latest member
liammiller

Latest Threads

Top