some puzzles

T

thomas

1.
---code--
class base{
public:
virtual void func();
};
class derive:public base{
virtual void func(); //1
};
---code--
As we know that Line 1 implements the function overloading,
what's the difference between "virtual void func();" and "void
func();" in L1?

2.why people sometimes define constructor/destructor virtual?
what if a pure virtual constructor/destructor?

3.
--code--
int *x = new int[0];
cout<<x<<endl;
--code--
the result is not 0, what happened?

4. when calling "delete []p;", how does the program know how many
elements should be destroyed?
 
P

Pascal Bourguignon

thomas said:
1.
---code--
class base{
public:
virtual void func();
};
class derive:public base{
virtual void func(); //1
};
---code--
As we know that Line 1 implements the function overloading,
what's the difference between "virtual void func();" and "void
func();" in L1?

That's the same difference as with 'final' methods in java.

2.why people sometimes define constructor/destructor virtual?
what if a pure virtual constructor/destructor?

constructor can't be defined as virtual AFAIK. destructurs must be
defined as virtual as soon as there is a virtual method, to allow
calling the right destructor (that is, the one of the exact class of
the object), when delete is called with a pointer to the object typed
as a superclass:

class A {
ResourceA* ra;
A(){ra=ra_alloc();}
virtual ~A(){
ra_free(ra);
}
};

class B {
ResourceB* rb
B(){rb=rb_alloc();}
virtual ~B(){
rb_free(rb);
}
};

int main(){
A* obj=new B();
delete obj; // <-- we want ~B to be called too here!
return 0;
}

3.
--code--
int *x = new int[0];
cout<<x<<endl;
--code--
the result is not 0, what happened?

There is only one null pointer.

4. when calling "delete []p;", how does the program know how many
elements should be destroyed?

new[] stores the size allocated in the allocated memory block.




Since these are probably homework, you won't have learned anything,
and be sure that any employer will detect it in the first five minute
of the interview. You probably won't get a job in C++ programming...

Next time, do your own homework!
 
T

thomas

As we know that Line 1 implements the function overloading,
That's the same difference as with 'final' methods in java.

I guess you mean that this method cannot be overloaded by child
classes if not defined virtual.
constructor can't be defined as virtual AFAIK.  destructurs must be
defined as virtual as soon as there is a virtual method, to allow
calling the right destructor (that is, the one of the exact class of
the object), when delete is called with a pointer to the object typed
as a superclass:
int main(){
    A* obj=new B();
    delete obj;  // <-- we want ~B to be called too here!
    return 0;
}
I think I got it!
another problem:
--code--
class A{
virtual int func();
};
class B{
virtual double func(); //is this overloading?
};
3.
--code--
   int *x = new int[0];
   cout<<x<<endl;
--code--
the result is not 0, what happened?

There is only one null pointer.  
So the x will always get one piece memory allocated? Then when will it
be freed?
If "delete []x" is never called, will it never be freed?
4. when calling "delete []p;", how does the program know how many
elements should be destroyed?

new[] stores the size allocated in the allocated memory block.
How is the memory organized? Is the first element any different(store
the size) with others?
Why calling "delete p" will not free all the memory if size is known?
Since these are probably homework, you won't have learned anything,
and be sure that any employer will detect it in the first five minute
of the interview.  You probably won't get a job in C++ programming...

Next time, do your own homework!
Thanks for your reply. Actually I'm self-learning c++, just want some
details clarified.
I desire to master the language, and am afraid of having no job after
graduation, so I gona work harder. :)
 
T

thomas

class A {
  ResourceA* ra;
  A(){ra=ra_alloc();}
  virtual ~A(){
      ra_free(ra);
  }

};

class B {
  ResourceB* rb
  B(){rb=rb_alloc();}
  virtual ~B(){
      rb_free(rb);
  }

};

int main(){
    A* obj=new B();
    delete obj;  // <-- we want ~B to be called too here!
    return 0;
The destructor overloading seems quite strange.
"virtual ~A();" in A, and "virtual ~B();" in B.
have different function names.
 
R

Richard Herring

In message
I guess you mean that this method cannot be overloaded by child
classes if not defined virtual.

If so, he's wrong. C++ has no direct equivalent to "final". The
"virtual" keyword in the derived class is redundant. It makes no
difference to the semantics of the class, but it may help to document
it.
 
D

Daniel T.

thomas said:
1.
---code--
class base{
public:
virtual void func();
};
class derive:public base{
virtual void func(); //1
};
---code--
As we know that Line 1 implements the function overloading,
what's the difference between "virtual void func();" and "void
func();" in L1?

There is none. At line 1, the 'virtual' keyword is optional.
2.why people sometimes define constructor/destructor virtual?

Nobody ever defines a constructor as virtual. Destructors are defined as
virtual so the base destructor will be called when a pointer to derived
is deleted.
what if a pure virtual constructor/destructor?

Destructors must be defined. You can have this:

class Foo {
public:
virtual ~Foo() = 0;
};

but you still have to define Foo::~Foo() somewhere. What the above does
is make the class abstract, even if all other member-functions are
defined.
3.
--code--
int *x = new int[0];
cout<<x<<endl;
--code--
the result is not 0, what happened?

'new' is guaranteed to return memory or throw. In the above, you newed a
block of memory of unspecified size, that can't be accessed for any
reason. "*x" would be undefined behavior.
4. when calling "delete []p;", how does the program know how many
elements should be destroyed?

How the system does unspecified by the language.
 
D

Daniel T.

thomas said:
I guess you mean that this method cannot be overloaded by child
classes if not defined virtual.

That is incorrect. It was defined virtual in the base class, so it can
be overridden by any derived class, even if some derived class in the
chain doesn't use the virtual keyword. For example:

class A { public: virtual int foo(); };

class B : public A { public: int foo(); };

class C : public B { public: int foo(); };

int main() {
C c;
A* a = &c;
a->foo(); // C::foo() will be called
}
I think I got it!
another problem:
--code--
class A{
virtual int func();
};
class B{
virtual double func(); //is this overloading?
};

No. "Two functions that appear in the same scope are overloaded if they
have the same name but have different parameter list." The above two
functions are not in the same scope and don't have a different parameter
list, so this is not an example of overloading.
3.
--code--
   int *x = new int[0];
   cout<<x<<endl;
--code--
the result is not 0, what happened?

There is only one null pointer.  

So the x will always get one piece memory allocated?

Correct. 'new' always returns memory, or throws.
If "delete []x" is never called, will it never be freed?
Correct.
4. when calling "delete []p;", how does the program know how many
elements should be destroyed?

new[] stores the size allocated in the allocated memory block.

How is the memory organized?

However the system wants. The organization isn't specified by the
standard.
Is the first element any different(store
the size) with others?
No.

Why calling "delete p" will not free all the memory if size is known?

Calling delete on memory that was allocated using new[] is undefined. It
might release all the memory, it might not. It might call all the
destructors, it might not. It might crash the program, it might not...
&c.
 
M

Marcel Müller

Pascal said:
That's the same difference as with 'final' methods in java.

No.

Daniel is right. It is just optional.


Example:

#include <stdio.h>

struct A
{ virtual void foo()
{ puts("A::foo()");
}
};

struct B : public A
{ void foo()
{ puts("B::foo()");
}
};

struct C : public B
{ void foo()
{ puts("C::foo()");
}
};

int main()
{ A* x = new C;
x->foo();
delete x;
return 0;
}


Marcel
 
V

Victor Bazarov

Marcel said:
No.

Daniel is right. It is just optional.


Example:

#include <stdio.h>

struct A
{ virtual void foo()
{ puts("A::foo()");
}
};

struct B : public A
{ void foo()
{ puts("B::foo()");
}
};

struct C : public B
{ void foo()
{ puts("C::foo()");
}
};

int main()
{ A* x = new C;
x->foo();
delete x;

Your program has undefined behaviour since 'A's destructor
is not virtual. Leave the 'delete' out, and it only has
a memory leak. Much better if you ask me.
return 0;
}


Marcel

V
 
R

red floyd

thomas said:
1.
---code--
class base{
public:
virtual void func();
};
class derive:public base{
virtual void func(); //1
};
---code--
As we know that Line 1 implements the function overloading,
what's the difference between "virtual void func();" and "void
func();" in L1?

2.why people sometimes define constructor/destructor virtual?
what if a pure virtual constructor/destructor?

3.
--code--
int *x = new int[0];
cout<<x<<endl;
--code--
the result is not 0, what happened?

4. when calling "delete []p;", how does the program know how many
elements should be destroyed?

All your answers can be found at
http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.2
 
B

Bo Persson

thomas said:
The destructor overloading seems quite strange.
"virtual ~A();" in A, and "virtual ~B();" in B.
have different function names.

No, they are not functions. They are destructors, which are special.


Bo Persson
 
J

Juha Nieminen

Bo said:
No, they are not functions. They are destructors, which are special.

Actually they *are* functions. They just are *unnamed* functions.
(The name of the class is used to refer to these unnamed functions, so
it looks almost like they were named, although they really aren't.)
 
A

Alf P. Steinbach

* Juha Nieminen:
Actually they *are* functions.

Yes, the category of "special member functions".

They just are *unnamed* functions.
(The name of the class is used to refer to these unnamed functions, so
it looks almost like they were named, although they really aren't.)

I'm sorry, that's incorrect.

The standard is quite clear that (1) constructors don't have names,
formally, and (2) destructors do have names, formally.

That thing about having name or not formally is just a formal device to
help invoke the right rules for look-up.

It's indirect and subtle and essentially a Very Bad Kludge that has lead
to many misunderstandings, and one shouldn't really think of it as
having any more significance than some beurocratic (speling?) rule that
formally certain persons don't have names, because that helps the
bureaucracy process their letters by invoking certain stiff rules.

Instead of such an indirect kludge, it would probably have been better
if just the the right processing rules were mentioned...


Cheers, & hth.,

- Alf
 

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,015
Latest member
AmbrosePal

Latest Threads

Top