class constructor and members

I

imutate

Some questions about ctors and class members

Is v private in the following ? If it is why put the declaration at
the top ? Is there any difference to putting it in the private section
?
The reference to v() defines the constructor, it will call v's
constructor, right ?

class vec
{
std::vector< celement > v;
public:
vec() : v() { }


If you declare an empty constructor like In the following is there any
difference to when it is left out ? Does C++ differ from other
languages in that you do not have to explicitely call the default ctor
from within the "programed" one.

class compos
{
int a;
double b;
public:
compos() { } // <- but there is nothing in it ?

Finally does this last example have the same results as the previous
one ?

class compos
{
int a;
double b;
public:
compos();

compos::compos
{ }
 
V

Victor Bazarov

Some questions about ctors and class members

Is v private in the following ? If it is why put the declaration at
the top ? Is there any difference to putting it in the private
section ?
The reference to v() defines the constructor, it will call v's
constructor, right ?

class vec
{
std::vector< celement > v;

Here 'v' is private.
public:
vec() : v() { }

And here you omit the end of the 'vec' definition for some reason.
If you declare an empty constructor like In the following is there any
difference to when it is left out ?
No.

Does C++ differ from other
languages in that you do not have to explicitely call the default ctor
from within the "programed" one.

I guess I don't understand the question. In C++ at this point you cannot
"call the default ctor from within". There is a proposal on the table to
add this functionality, but it's not going to make it into the language
any time soon.
class compos
{
int a;
double b;

'a' and 'b' are private.
public:
compos() { } // <- but there is nothing in it ?

Yep, nothing. Both members are left uninitialised.
Finally does this last example have the same results as the previous
one ?

class compos
{
int a;
double b;
public:
compos();

Missing:

};
compos::compos
{ }

Sure. You just moved the definition outside, you didn't change what
the function does and how it does it.

V
 
I

imutate

Thanks for the answers, just a few things.

Victor said:
And here you omit the end of the 'vec' definition for some reason.

You mean the rest of the definitions (if there were any) and the end
bracket ? Sorry I thought you would prefer brevity, it is one less
line for you to read ;}
I guess I don't understand the question. In C++ at this point you cannot
"call the default ctor from within". There is a proposal on the table to
add this functionality, but it's not going to make it into the language
any time soon.

In some other languages if you want to override the default constructor
you have to explicitly call the default constructor otherwise you will
be in big trouble.. nothing will be created. So in C++ it is a bit
strange seeing empty brackets or just some variable set, where normally
there would be a function call. This was why I was asking about the
empty brackets they may be empty but there is still a valid
constructor. So a natural question to ask is: is the default
constructor called at the begining ?

class compos
{
int a;
double b;
public:
compos();
};

compos::compos()
{
// is it called before this:
a = 1;
}
 
R

Ron Natalie

Thanks for the answers, just a few things.
In some other languages if you want to override the default constructor
you have to explicitly call the default constructor otherwise you will
be in big trouble.. nothing will be created.

Constructors do NOT create object in C++.
You can't call them. The constructor is called for you by the
implementation in the proper course during the creation of
each object.

You're also abusing the terminology. The "default constructor"
is one that can be called with no arguments. If you do not define
*ANY* constructors, the compiler implicitly generates an empty one
for you. If you want to define your own, there's NOTHING else
for you to do but add the stuff you want done differently.

Constructors for all the base classes and non-static data members
(subobjects) are called as a matter of course as well before the
body of the constructor you define for the class is executed.
Again there is nothing you can to do change this. The only thing
that you can affect is the selection of which constructor by what
arguments are given to the (sub)object creation.
 
I

imutate

Ron said:
Constructors do NOT create object in C++.

Eh, well what do they do then ?
You can't call them.

Are you sure you are right ? Just to be pedantic I thought I saw on the
faq that some people did this by calling one constructor from another,
but the faq did say it was a very bad thing to do this, but it did not
say that it was not possible.
The constructor is called for you by the
implementation in the proper course during the creation of
each object.

You're also abusing the terminology. The "default constructor"
is one that can be called with no arguments.

Confusing, well what would you call it then (the normal constructor?)
look at this object pascal as a comparison:

Constructor TMyObject.Create(source : TMyObject); overload;
begin
Create;
CopyFrom(source);
end;

The Create call calls the underlying constructor.
If you do not define
*ANY* constructors, the compiler implicitly generates an empty one
for you.

OK, is it called the normal constructor ? But if it is empty how is
the object created ?
If you want to define your own, there's NOTHING else
for you to do but add the stuff you want done differently.

Constructors for all the base classes and non-static data members
(subobjects) are called as a matter of course as well before the
body of the constructor you define for the class is executed.
Again there is nothing you can to do change this. The only thing
that you can affect is the selection of which constructor by what
arguments are given to the (sub)object creation.

And if you leave out those objects then they won't get created
correctly, or something else ?
 
I

Ian Collins

Eh, well what do they do then ?
If they do anything, they initialise the object. For an automatic
variable, a constructor is called with this pointing to an area in
automatic storage (typically the stack) and for a dynamic object, it
points to the memory returned by new.
 
R

Ron Natalie

Eh, well what do they do then ?

They perform initialization.
Are you sure you are right ?

Absolutely. The words come straight out of the standard. Constructors
do not participate in name resolution. They can't be called by code.
Any syntax that appears to do so is either illegal or doing something
else.

For instance:
class X {
public:
X() { }
X(int a) {
X();
}
};

The line in the second (non-default) constructor isn't calling anything.
It makes a temporary default constructed temporary object that vanishes
when the expression it is used ends.
Just to be pedantic I thought I saw on the
faq that some people did this by calling one constructor from another,
but the faq did say it was a very bad thing to do this, but it did not
say that it was not possible.

The FAQ does not say it. It's not just a bad thing, it's not possible.
If you have code that is common to more than one constructor you need
to put it in another member function that can be called.

There are some people who espouse hacks such as placement constructing
an object on top of the one under construction but it is frowned upon
and also involves implementation-specific or undefined behavior.
Confusing, well what would you call it then (the normal constructor?)
look at this object pascal as a comparison:

I didn't invent the terms. But default constructor is one called with
no arguments whether its generated by the compiler OR one you write.
The Create call calls the underlying constructor.


OK, is it called the normal constructor ? But if it is empty how is
the object created ?
It is important for you to realize that the CREATION: be it as
a result of a locally declared variable, a temporary, or dynamic
creation via new embodies two things:
1. Allocation of storage for the object (which you really don't
have any control over other than the context of the way you
create the object, this code is all automagically emitted by the
compiler for you).
2. Initialization, which involves invoking constructors for
class objects and doing other initialization for more primitive
types.

he standard uses the terms "implicitly declared" and "implicitly
defined" for the four functions it will generate for you in certain
circumstances:
a default constructor (if no constructors are declared)
a copy constructor (if no copy constructor is declared)
a copy-assignment operator (if not declared)
a destructor (if not declared)


And if you leave out those objects then they won't get created
correctly, or something else ?

No, if they are class objects, their default constructors (implicit
or explicitly defined) are invoked. If they are not class objects
then rather stupid and arcane initialization rules are invoked
depending on the context (it is a major freaking defect in C++
that default construction of non-class objects isn't always the
same, but too much whining and crying by ex-C programmers ruined
this).
 
V

Victor Bazarov

OK, is it called the normal constructor ?

There are four functions that if not explicitly declared are declared
and often defined for you. They are the *default* constructor, the
*copy* constructor, the destructor, and the *copy* assignment operator.
All constructors are "normal". Not one is "more normal" than others.
But if it is empty how is
the object created ?

An object is created by allocating storage for it. The object is
initialised by calling a constructor. Both operations are performed
by the C++ run-time, and not by you. You can create an object by
definining it or by using 'new' or by using the syntax that causes
a temporary object to be created. You don't control explicitly what
constructor is called, but you can do a lot to steer the system to
calling the "right" one.

Right. To clarify, you can control whether certain members are
initialsed or left uninitialised by mentioning them in, or leaving
out of, the constructor initialiser list.
And if you leave out those objects then they won't get created
correctly, or something else ?

The process of initialising members of a class is described in most
decent books. What book on C++ are you reading?

V
 
R

Ron Natalie

Victor said:
There are four functions that if not explicitly declared are declared
and often defined for you. They are the *default* constructor, the
*copy* constructor, the destructor, and the *copy* assignment operator.

Note that declaration of ANY constructor inhibits the implicit
generation of the default constructor. A class needs not have
a default constructor if not default initialized.
 
E

Earl Purple

Ron said:
There are some people who espouse hacks such as placement constructing
an object on top of the one under construction but it is frowned upon
and also involves implementation-specific or undefined behavior.


You mean doing this:

class X
{
public:

explicit X( int a );
X ( int a, const char * b )
{
new( this ) X( a );
// do some more
}
};

Not sure doing so would necessarily be undefined. It might depend on
what is the nature of X and I wouldn't recommend actually doing it.
 
R

Ron Natalie

Earl said:
You mean doing this:

class X
{
public:

explicit X( int a );
X ( int a, const char * b )
{
new( this ) X( a );
// do some more
}
};

Not sure doing so would necessarily be undefined. It might depend on
what is the nature of X and I wouldn't recommend actually doing it.
It runs the constructors of the subobjects twice. This may or may
not be acceptible.
 

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,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top