Synthesized and non-inherited class members

L

lovecreatesbea...

Could you tell me how many class members the C++ language synthesizes
for a class type? Which members in a class aren't derived from parent
classes?

I have read the book The C++ Programming Language, but there isn't a
detail and complete description on all the class members, aren't they
important to class composing? Could you explain the special class
behavior in detail? Thank you very much.
 
S

Salt_Peter

Could you tell me how many class members the C++ language synthesizes
for a class type? Which members in a class aren't derived from parent
classes?

I have read the book The C++ Programming Language, but there isn't a
detail and complete description on all the class members, aren't they
important to class composing? Could you explain the special class
behavior in detail? Thank you very much.

Please read the following:
http://www.parashift.com/c++-faq-lite/how-to-post.html
 
L

lovecreatesbea...

"Salt_Peter дµÀ£º"

Thank you.

Do you mean it is a homework problem or it is a FAQ problem? Why do you
direct me to that link? I ever read Scott Meyers popular book Effective
C++, in one print of its second edition, he said that a pair of &
operators are synthesized by the language.

I also think this question is important and not difficult to me. If you
experts know the answer exactly, I would like to ask for your help
sincerely.
 
L

lovecreatesbea...

"(e-mail address removed) дµÀ£º
"
"Salt_Peter дµÀ£º"

Thank you.

Do you mean it is a homework problem or it is a FAQ problem? Why do you
direct me to that link? I ever read Scott Meyers popular book Effective
C++, in one print of its second edition, he said that a pair of &
operators are synthesized by the language.

I also think this question is important and not difficult to me.

Sorry for the typo above, I mean it's important and difficult to me,
and come here asking for your help. Please help me.
 
S

Salt_Peter

"Salt_Peter дµÀ£º"

Thank you.

Do you mean it is a homework problem or it is a FAQ problem? Why do you
direct me to that link? I ever read Scott Meyers popular book Effective
C++, in one print of its second edition, he said that a pair of &
operators are synthesized by the language.

I also think this question is important and not difficult to me. If you
experts know the answer exactly, I would like to ask for your help
sincerely.

Those aren't & operators. You are referring to a copy constructor and
an assignment operator.
Scott Meyers' book explains that quite well.
The following are generated for you if a class is declared and defined
as empty and _if_ these are needed:

class A { };

// def ctor
A::A() { }
// copy ctor
A::A(const& copy) { }
// destructor
A::~A() { }
// assignment operator
A& Aoperator=(const A& rhv) { }

What happens if you add members depends on whether the members are
primitive types or other user-types. If primitives, these are
allocated, not initialized and bit-copied, if user-types, their
corresponding def ctors/d~tors/copies are invoked.
It would be nice if you stated which case you wanted to investigate.
You need to specify which situation you'ld like considered because a
book can be written on that subject alone. A simple example would do
with members, perhaps.

Otherwise, i'll end up rambling in all directions getting into endless
arguements with a few hundred people about what exactly happens at
exactly what point in time. I can seriously think of over 10 different
configurations off the top of my head involving everything from
primitive members, abstract bases, pure virtual diamonds, members of
members, virtual d~tors, private derived classes, containers, embedded
classes, and the list goes on and on.
 
L

lovecreatesbea...

Salt_Peter said:
Those aren't & operators. You are referring to a copy constructor and
an assignment operator.
Scott Meyers' book explains that quite well.
The following are generated for you if a class is declared and defined
as empty and _if_ these are needed:

class A { };

// def ctor
A::A() { }
// copy ctor
A::A(const& copy) { }
// destructor
A::~A() { }
// assignment operator
A& Aoperator=(const A& rhv) { }

What happens if you add members depends on whether the members are
primitive types or other user-types. If primitives, these are
allocated, not initialized and bit-copied, if user-types, their
corresponding def ctors/d~tors/copies are invoked.
It would be nice if you stated which case you wanted to investigate.
You need to specify which situation you'ld like considered because a
book can be written on that subject alone. A simple example would do
with members, perhaps.

Otherwise, i'll end up rambling in all directions getting into endless
arguements with a few hundred people about what exactly happens at
exactly what point in time. I can seriously think of over 10 different
configurations off the top of my head involving everything from
primitive members, abstract bases, pure virtual diamonds, members of
members, virtual d~tors, private derived classes, containers, embedded
classes, and the list goes on and on.

Hello peter, thank you very much for the reply.

The author called it operator &. If you have the corresponding print of
his book. He stated the mistake in errata <url:
http://www.aristeia.com/BookErrata/ec++2e-errata_frames.html>. I will
quote the errata of the description on synthesized operator& for
further discussion.

In the following errata, Mr. Meyers mentioned two more glossary:

1. "built-in address-of operator" and
2. "global operator& function".

Is there the third name 3. "class defined operator"?

What do the built-in, global things do to a class. Can they be data
members or member functions? How do they affect the other members are
not built-in and global in a class?

I still want to know which members will (or have the chance to) be
provided automatically for a class? Which members can not be inherited
from the parent classes? Could you master help me?

Thank you.

--quote---
http://www.aristeia.com/BookErrata/ec++2e-errata_frames.html

! 2/10/00 ic 212 A class declaring no operator& function(s)
9/10/01
cxh 213 does NOT have them implicitly declared. Rather,
245 compilers use the built-in address-of operator
246 whenever "&" is applied to an object of that
type. This behavior, in turn, is technically
not an application of a global operator&
function. Rather, it is a use of a built-in
operator.
I eliminated mention of operator& as an
automatically generated function and adjusted the
index to eliminate entries for the removed
material.
--quoting ends---
 
S

Salt_Peter

Hello peter, thank you very much for the reply.

The author called it operator &. If you have the corresponding print of
his book. He stated the mistake in errata <url:
http://www.aristeia.com/BookErrata/ec++2e-errata_frames.html>. I will
quote the errata of the description on synthesized operator& for
further discussion.

In the following errata, Mr. Meyers mentioned two more glossary:

1. "built-in address-of operator" and
2. "global operator& function".

These are free compiler operators that are provided automatically. They
are not synthesized.
Adress_of returns the variable's address (not the class).
Is there the third name 3. "class defined operator"?

No, there is no op* synthesized except for pointers and references.
The op* is only predefined for primitive numerics where its a
mutiplication.
What do the built-in, global things do to a class. Can they be data
members or member functions? How do they affect the other members are
not built-in and global in a class?

The built-ins are provided by the compiler to support the language.
There is nothing magic about how they work either.

class A { };
int main()
{
A a; // a variable
A* p_a; // a pointer to nothing
p_a = &a; // a pointer to the a variable (&a is address_of a)
A& r_a(a); // a reference to to a (r_a is a reference to a)
}
I still want to know which members will (or have the chance to) be
provided automatically for a class? Which members can not be inherited
from the parent classes? Could you master help me?

i'm no master.
All virtual member functions are inherited by a Child class. Of course,
that doesn't inlude constructors and destructors nor any operator.
Which makes perfect sense since these are specialized for the Parent
class.
Look at it this way, any "function" that generates / initializes an
object of type Parent can't be overloaded or overridden in its
derivatives. The Child class can't overide a ctor, for example.

Why don't you simply investigate the issue:

#include <iostream>

class A
{
public:
A() { std::cerr << "A()\n"; }
virtual ~A() { std::cerr << "~A()\n"; }
A(const A& copy) { std::cerr << "A(...) copy\n"; }
A& operator=(const A& rhv)
{
std::cerr << "A op=\n";
if(&rhv == this) return *this;
// assign members
return *this;
}
};

class Child : public A
{
};

int main()
{
Child child; // ctor
Child another = child; // copy
child = another; // assignment

Child* p_child = &child; // pointer to child
std::cout << "p_child = " << p_child << std::endl;
}

/*
A()
A(...) copy
A op=
p_child = 0x7fffc20ce6e0
~A()
~A()
*/
 
L

lovecreatesbea...

Salt_Peter said:
(e-mail address removed) wrote:

These are free compiler operators that are provided automatically. They
are not synthesized.
Adress_of returns the variable's address (not the class).


No, there is no op* synthesized except for pointers and references.
The op* is only predefined for primitive numerics where its a
mutiplication.

The built-ins are provided by the compiler to support the language.
There is nothing magic about how they work either.

Thank you again, Peter.

I understand that, for a user-defined class, operators like operator+,
operator-, operator*, operator/ should be overridden to make the class
do plus, minus, multiple and division respectively. (and only
assignment operator is the exception, right?)

you mean there are no built-in (or global) operators provided for a
user-defined class, do I understand you correctly? I can't distinguish
synthesized, predefined or automatically provided members or behavior.

What are are the differences between built-in and global things on a
user-defined class?

When a programmer defines a class, are there some built-in (or global)
operators or functions be added to the class automatically or
synthesized by the language.
class A { };
int main()
{
A a; // a variable
A* p_a; // a pointer to nothing
p_a = &a; // a pointer to the a variable (&a is address_of a)
A& r_a(a); // a reference to to a (r_a is a reference to a)
}


i'm no master.
All virtual member functions are inherited by a Child class. Of course,
that doesn't inlude constructors and destructors nor any operator.
Which makes perfect sense since these are specialized for the Parent
class.
Look at it this way, any "function" that generates / initializes an
object of type Parent can't be overloaded or overridden in its
derivatives. The Child class can't overide a ctor, for example.

Are there only these four members:

default constructor,
copy constructor,
assignment operator,
destructor

will not be inherited from parent classes?

As they will be provided (synthesized or predefined) for the child
classes by the language.

(But how what about the others, how many in total members will be
provided automatically? Which are those?

And which can not be inherited? I ever wrote some example code, but
still can not get a complete and detail list of these special
functions. Thank you.)
 
S

Salt_Peter

Thank you again, Peter.

I understand that, for a user-defined class, operators like operator+,
operator-, operator*, operator/ should be overridden to make the class
do plus, minus, multiple and division respectively. (and only
assignment operator is the exception, right?)
Yes


you mean there are no built-in (or global) operators provided for a
user-defined class, do I understand you correctly? I can't distinguish
synthesized, predefined or automatically provided members or behavior.

Yes, except for address_of and reference operator, as noted by the
author.
Type t;
Type& ref = t; // reference
Type* p = &t; // address_of
What are are the differences between built-in and global things on a
user-defined class?

Built-in means provided by the compiler. global means globally
accessible.
When a programmer defines a class, are there some built-in (or global)
operators or functions be added to the class automatically or
synthesized by the language.

Yes, we've discussed them all, ctor, copy, d~tor and op== are
automatically generated for you. The address_of and reference are
builtin. What you need to know is what happens when you start providing
you own ctors.
Are there only these four members:

default constructor,
copy constructor,
assignment operator,
destructor

will not be inherited from parent classes?

None are "inherited". The parent class can only use them. In some
cases, the destructor is declared as virtual to support polymorphism,
in that case its the virtuality thats inherited. The Child class needs
its own ctors, d~tor and op=.
As they will be provided (synthesized or predefined) for the child
classes by the language.

That doesn't change the fact that the Child class needs its own. When
the Child type is used to create an object, the compiler needs a base
class ctor to complete the creation of the object (2 ctors are
invoked).
(But how what about the others, how many in total members will be
provided automatically? Which are those?

That has already been discussed.
Look at it this way, if you write a class without definitions, isn't
the compiler still able to generate, copy, destroy and assign the
object? How does it do that?

class A { };

int main()
{
A a; // ctor
A another(a); // copy ctor
a = another; // assignment op
std::cout << "&a = " << &a << std::endl; // address_of
A& ref = another; // reference
std::cout << "&ref = " << &ref << std::endl;
// a = a + another; // fails, why?
}
And which can not be inherited? I ever wrote some example code, but
still can not get a complete and detail list of these special
functions. Thank you.)

Thats a deep issue. What is inherited is any public or protected
function that isn't a ctor, d~tor or assignment. Why don't you code
these? Write 2 classes with std::cerr outputs in their functions and
watch what happens. You should leave inheritance out of the picture
until you understand how classes work.
 
L

lovecreatesbea...

Salt_Peter said:
Yes, except for address_of and reference operator, as noted by the
author.
Type t;
Type& ref = t; // reference
Type* p = &t; // address_of

I think the & in that book doesn't mean the reference. The author
referred them to const address-of, non-const address-of operators. I
don't have the book handy and may be wrong.
Built-in means provided by the compiler. global means globally
accessible.

Operators including the assignment operator are all built-in things in
the language. All functions including ctors, dctor are all not
built-ins, right?

And only operators are global, right?

How can the built-in and global properties affect a class?
Yes, we've discussed them all, ctor, copy, d~tor and op== are
automatically generated for you. The address_of and reference are
builtin. What you need to know is what happens when you start providing

That is op= but not op== [double equal marks], right?

Are there exactly 6 members:
ctor
copy ctor
dctor
op=
& (address-of)
& (reference)
will be provided automatically for a class?

I even learnt that someone mentioned two more:
, (comma)
.. (dot)

I am still not clear on the exact list of all automatically provided
members (data and or functions).
you own ctors.


None are "inherited". The parent class can only use them. In some
cases, the destructor is declared as virtual to support polymorphism,
in that case its the virtuality thats inherited. The Child class needs
its own ctors, d~tor and op=.


That doesn't change the fact that the Child class needs its own. When
the Child type is used to create an object, the compiler needs a base
class ctor to complete the creation of the object (2 ctors are
invoked).


That has already been discussed.
Look at it this way, if you write a class without definitions, isn't
the compiler still able to generate, copy, destroy and assign the
object? How does it do that?

class A { };

int main()
{
A a; // ctor
A another(a); // copy ctor
a = another; // assignment op
std::cout << "&a = " << &a << std::endl; // address_of
A& ref = another; // reference
std::cout << "&ref = " << &ref << std::endl;
// a = a + another; // fails, why?
}


Thats a deep issue. What is inherited is any public or protected
function that isn't a ctor, d~tor or assignment. Why don't you code

Thanks for this confirmation. I'll code more exercises and go back to
ask for your help when I get problems.

(but I ever leant that even private members can be inherited though
cann't be referred to in the child classes or objects of child classes,
am I right?)
 
S

Salt_Peter

I think the & in that book doesn't mean the reference. The author
referred them to const address-of, non-const address-of operators. I
don't have the book handy and may be wrong.


Operators including the assignment operator are all built-in things in
the language. All functions including ctors, dctor are all not
built-ins, right?

No, def ctor, copy ctor, d~tor and op= are not bulit-in. They are
simply provided if you chose not to define them. This is an important
characteristic because if i write:

A
{
int n;
public:
A(int x) : n(x) { }
};

The compiler now ceases to generate the default ctor: A() : n() { }. It
does, however, continue to supply a copy ctor and the assigment
operator (which do simple bit-copies of the members.
And only operators are global, right?

not neccessarily, operators can be members of the class. And any
function can be global, except for ctors, copies and assignment ops.
How can the built-in and global properties affect a class?
Yes, we've discussed them all, ctor, copy, d~tor and op== are
automatically generated for you. The address_of and reference are
builtin. What you need to know is what happens when you start providing

That is op= but not op== [double equal marks], right?

no, thats a typo, the op== must be defined and is usually global.
Are there exactly 6 members:
ctor
copy ctor
dctor
op=
& (address-of)
& (reference)
will be provided automatically for a class?

I even learnt that someone mentioned two more:
, (comma)
. (dot)

and there are a few others like * and -> for pointers, * for
dreferencing, resolution operator :: and so on.
I am still not clear on the exact list of all automatically provided
members (data and or functions).

The best way to learn these is by coding.
 
L

lovecreatesbea...

Salt_Peter said:
(e-mail address removed) wrote:

The best way to learn these is by coding.

Thank you for helping me. I am afraid to code blindly for there are so
many possibilities. I can code more correctly and efficiently when I
know the answers for example to these two questions:

1. Which members are provided automatically (predefined/synthesized)
for a class?

2. Which members can't be inherited from parent classes?

I am also listening to you; can you talk about those deeper things when
you have time?
 
B

BobR

(e-mail address removed) wrote in message ...
Salt_Peter wrote:


Thank you for helping me. I am afraid to code blindly for there are so
many possibilities. I can code more correctly and efficiently when I
know the answers for example to these two questions:

1. Which members are provided automatically (predefined/synthesized)
for a class?

2. Which members can't be inherited from parent classes?

I can understand you wanting to know specifics, but, you need to try things,
experiment and do tests. That means 'coding'.

As an example, last week I was checking out a sample:

// -------
class Base3{};
class Derived3 : public Base3{};

void TellMe( Base3 &a, std::string &rtn){
rtn = "I'm an type Base3!";
return;
}

{ // main() or function
std::string Iam;
Derived3 Dev; //class Derived3 : Base3{};
TellMe( Dev, Iam);
std::cout << Iam << std::endl;
}
// -------

(Note how 'empty' those classes are (in the code. compiler fills them up).)
Compiled and ran fine. So, I might have used that for years. But then I did:

// -------
void TellMe( Base3 &a, std::string &rtn){
rtn = "I'm an type Base3!";
Derived3 *cp = dynamic_cast<Derived3*>( &a );
if(cp) rtn += " It's also an Derived3.";
return;
}
// -------

Now, the problem showed up! The fix was simple:

// -------
class Base3{ public: virtual ~Base3(){} }; // add 'virtual'
class Derived3 : public Base3{};
// -------

In this case, without the virtual destructor, the compiler told me, "Hey man,
you got a problem with the Base3 in Derived3!!". You can learn much with just
your compiler. ( books? I don't need no stinkin' books! (ah, but the guys
that wrote the books have experience, so, read the books!)).

Don't be afraid to try things. Make something, then try to think of ways to
break it (tests), experiment.
Find ways to prove to yourself whether something is true or false (hint: many
couts (Salt Peter's earlier post)).

In running a nuclear [1] reactor, you really need to know what you are doing.
Coding is different, blowing up a (toy) program and blowing up the world are
two very different things.

Don't chase the rainbow looking for the pot of gold, just pick up the
diamonds along the way.

"Don't fear, when you get stuck, come here."
[1] - that's "nuke-Y-lar" for you bushites. <G>
 
L

lovecreatesbea...

BobR said:
(e-mail address removed) wrote in message ...

I can understand you wanting to know specifics, but, you need to try things,
experiment and do tests. That means 'coding'.

As an example, last week I was checking out a sample:

// -------
class Base3{};
class Derived3 : public Base3{};

void TellMe( Base3 &a, std::string &rtn){
rtn = "I'm an type Base3!";
return;
}

{ // main() or function
std::string Iam;
Derived3 Dev; //class Derived3 : Base3{};
TellMe( Dev, Iam);
std::cout << Iam << std::endl;
}
// -------

(Note how 'empty' those classes are (in the code. compiler fills them up).)
Compiled and ran fine. So, I might have used that for years. But then I did:

// -------
void TellMe( Base3 &a, std::string &rtn){
rtn = "I'm an type Base3!";
Derived3 *cp = dynamic_cast<Derived3*>( &a );

This is down-casting and the pointer of object of child class Derived3
is pointing to object of parent class Base3. I don't read a warning
message from g++ for this line, but get a message for a similar line of
my code at line 16, why?

$ make
g++ -std=c++98 -pedantic a.cpp -c -o a.o
a.cpp: In function `int main()':
a.cpp:16: warning: dynamic_cast of `Base3 b' to `class Derived3*' can
never
succeed
g++ -std=c++98 -pedantic a.o -o a.out
$

/*a.cpp*/
#include <iostream>

class Base3{public: virtual ~Base3(){}};
class Derived3 : public Base3{};

void TellMe( Base3 &a, std::string &rtn){
rtn = "I'm an type Base3!";
Derived3 *cp = dynamic_cast<Derived3*>( &a );
if(cp) rtn += " It's also an Derived3.";
return;
}

int main(){
Base3 b;
Derived3 d;
Derived3 *p1 = dynamic_cast<Derived3*>(&b); //line 16
 
B

BobR

(e-mail address removed) wrote in message ...
This is down-casting and the pointer of object of child class Derived3
is pointing to object of parent class Base3.

The Base3 reference (a) is 'holding' an object of Derived3, or object of type
Base3, or object of type derived from Base3, etc.. Read on....
I don't read a warning
message from g++ for this line, but get a message for a similar line of
my code at line 16, why?

$ make
g++ -std=c++98 -pedantic a.cpp -c -o a.o
a.cpp: In function `int main()':
a.cpp:16: warning: dynamic_cast of `Base3 b' to `class Derived3*'
can never succeed
g++ -std=c++98 -pedantic a.o -o a.out
$

My docs don't show a 'c++98' option for '-std='( which is for 'C', and
supposed to be ignored for 'C++'). Try removing the '-std=c++98' (unless your
docs say it is supported).
(of course you will still get the *warning* because you are casting a base to
a derived, and the compiler has determined that in this situation (line 16)
it can never succeed. In my little 'TellMe()', it's not sure, so doesn't
warn. Pretty smart compiler, eh?).

I compiled on MinGW(GCC3.3.1). What version are you using?
I can't imagine a newer standard would forbid downcasting, it would break
much code.
A failed downcast (line 16) should just produce a zero (or NULL if you
prefer).

<loose wording>
Why does the compiler 'warn'? One reason could be the possibility to 'slice'
the object. In my example, there is nothing there. But, what if I added
things to the derived class. Those added things could be removed (like during
a copy operation) under some conditions. (look up 'pure virtual' and "object
slicing" if you don't know about them.). Most books demonstrate that, and you
should try the examples (if you haven't already.).
A derived class will almost always have things that the base class
doesn't[1]. The compiler warns you, "Hey, you sure you want to do that? You
might try to call a function that isn't there!". A dog is always an animal,
but, an animal is not always a dog. Ever try to pet a rattlesnake? (they
won't chase cars or retrieve a stick either!<G>).

[1] - or different, like defined a pure virtual.
/*a.cpp*/
#include <iostream>

class Base3{public: virtual ~Base3(){}};
class Derived3 : public Base3{};

void TellMe( Base3 &a, std::string &rtn){
rtn = "I'm an type Base3!";
Derived3 *cp = dynamic_cast<Derived3*>( &a );
if(cp) rtn += " It's also an Derived3.";
return;
}

int main(){
Base3 b;
Derived3 d;
Derived3 *p1 = dynamic_cast<Derived3*>(&b); //line 16

if( p1 ){ // check downcast
std::cout<<"dynamic_cast<Derived3*>(&b); GOOD"<<std::endl;
}
else{
std::cout<<"dynamic_cast<Derived3*>(&b); FAILED"<<std::endl;
}
// compile and run it, you should *always* see 'FAILED'.
// that is what the compiler was warning about.
Base3 *p2 = dynamic_cast<Base3*>(&d);

if( p2 ){ // check upcast
std::cout<<"dynamic_cast<Base3*>(&d); GOOD"<<std::endl;
}
else{
std::cout<<"dynamic_cast<Base3*>(&d); FAILED"<<std::endl;
}
// should see 'GOOD'.

Derived3 *p3 = dynamic_cast<Derived3*>( p2 );
if( p3 ){ // cast it back
std::cout<<"dynamic_cast<Derived3*>( p2 ); GOOD"<<std::endl;
}
else{
std::cout<<"dynamic_cast<Derived3*>( p2 ); FAILED"<<std::endl;
}
// should see 'GOOD'.

But, again, my point was - code. If you were reading a book written using an
old compiler, the author may not have been aware of the warning you got by
trying the code.

[ experts - corrections welcomed ]
 

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

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top