473,582 Members | 3,083 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Virtual destructor

When i compile my program with the -ansi -Wall -pedantic
flags,
i get this warning: `class vechile' has virtual functions
but non-virtual destructor, and the same with my
sub-classes. But when i add a virtual destructor like this :

" virtual ~vechile". I get this error:
Undefined first referenced
symbol in file
vtable for vechile /var/tmp//ccC9yD6Z.o
ld: fatal: Symbol referencing errors. No output written to
a.out
collect2: ld returned 1 exit status
Can anyone help me?

Oct 5 '05 #1
26 3961
Ian
pmizzi wrote:
When i compile my program with the -ansi -Wall -pedantic
flags,
i get this warning: `class vechile' has virtual functions
but non-virtual destructor, and the same with my
sub-classes. But when i add a virtual destructor like this :

" virtual ~vechile". I get this error:


You haven't provides a body for the destructor. If it does nothing ,
then ~vechile() {} will suffice.

Ian
Oct 5 '05 #2
pmizzi wrote:
When I compile my program with the -ansi -Wall -pedantic flags,
I get this warning: `class vechile' has virtual functions
but non-virtual destructor,
It's a warning. Ignore it.
and the same with my sub-classes.
But, when I add a virtual destructor like this:

"virtual ~vechile", I get this error:

Undefined first referenced
symbol in file
vtable for vechile /var/tmp//ccC9yD6Z.o
ld: fatal: Symbol referencing errors. No output written to
a.out
collect2: ld returned 1 exit status

Can anyone help me?


Don't define a virtual destructor if you don't need one.
If you really need a virtual destructor,
you will need virtual constructors as well.
No function should ever delete an object
that was allocated by the calling function and,
in C++, it is poor programming practice
to require the calling program
to explicitly delete an object through a pointer
returned by a function that allocated the object.
Oct 5 '05 #3
"E. Robert Tisdale" <E.************ **@jpl.nasa.gov > wrote in message
news:di******** **@nntp1.jpl.na sa.gov...
pmizzi wrote:
When I compile my program with the -ansi -Wall -pedantic flags,
I get this warning: `class vechile' has virtual functions
but non-virtual destructor,
It's a warning. Ignore it.


It is a warning that should not be ignored in almost all cases. A virtualy
destructor is only rarely unnecessary. Even then, not defining virtual would
be a timebomb.

Deleting a polymorphic object through a base class pointer is very common.
It is undefined behavior when the destructor is non-virtual in that case.
and the same with my sub-classes.
But, when I add a virtual destructor like this:

"virtual ~vechile", I get this error:

Undefined first referenced
symbol in file
vtable for vechile /var/tmp//ccC9yD6Z.o
ld: fatal: Symbol referencing errors. No output written to
a.out
collect2: ld returned 1 exit status

Can anyone help me?


Don't define a virtual destructor if you don't need one.


That is very rarely the case.
If you really need a virtual destructor,
you will need virtual constructors as well.
Not at all. Using a function to make the decision on what object to
construct and to return a base object pointer is very common:

Base * read_object(/* ... */)
{
/* ... */
return some_condition
? new Derived1
: new Derived2;
}

/* ... */

Base * base = read_object(/* ... */);
No function should ever delete an object
that was allocated by the calling function
I can think of a linked-list implementation that has a function, which
removes objects. Surely the objects would not be allocated in that function,
yet deleted in there.
and,
in C++, it is poor programming practice
to require the calling program
to explicitly delete an object through a pointer
returned by a function that allocated the object.


See the read_object function above. How do you propose we delete the
returned object? Of course approach is to return a suitable smart pointer
that communicates precisely the transfer of ownership, which in turn means
that the object will be deleted outside of the allocating function.

Ali

Oct 5 '05 #4
Ali Çehreli wrote:
E. Robert Tisdale wrote:
If you really need a virtual destructor,
you will need virtual constructors as well.


Not at all. Using a function to make the decision on what object to
construct and to return a base object pointer is very common:

Base* read_object(/* ... */) {
/* ... */
return some_condition? new Derived1: new Derived2;
}

/* ... */

Base* base = read_object(/* ... */);


But it isn't good programming practice in C++.
Your program already knows about types Derived1 and Derived2
so you might as well use them in the calling program.

A virtual constructor is more "extensible ".
See Bjarne Stroustrup, "The C++ Programming Language: Third Edition",
Chapter 15: Class Hierarchies, Section 6: Free Store,
Subsection 2: Virtual constructors, pages 424-5.
Oct 5 '05 #5
"E. Robert Tisdale" <E.************ **@jpl.nasa.gov > wrote in message
news:di******** *@nntp1.jpl.nas a.gov...
Ali Çehreli wrote:
E. Robert Tisdale wrote:
If you really need a virtual destructor,
you will need virtual constructors as well.
Not at all. Using a function to make the decision on what object to
construct and to return a base object pointer is very common:

Base* read_object(/* ... */) {
/* ... */
return some_condition? new Derived1: new Derived2;
}

/* ... */

Base* base = read_object(/* ... */);


But it isn't good programming practice in C++.


Himmm... I don't see what you mean.

Even Stroustrup refers to such a use in C++ in the pages you quoted. My
read_object does exactly the same thing as his Ival_maker::dia l does. Maybe
naming it as "factory method" might
Your program already knows about types Derived1 and Derived2
so you might as well use them in the calling program.
My program knows of them, but the translation unit does not know of them. We
don't always mention the physical structure of code in our posts, but you
can assume that the declaration is

Base * read_object(/* ... */);

and the user is

Base * base = read_object(/* ... */);

So, Derived1 and Derived2 are know only in another translation unit, where
read_object is defined.
A virtual constructor is more "extensible ".
It is not more extensible than a function like read_object; you can extend
read_object any way we like. Besides, their application are very different:
read_object returns a brand new object, virtual constructor copies an
existing object. That's why I use virtual constructor in some of my copy
constructors.
See Bjarne Stroustrup, "The C++ Programming Language: Third Edition",
Chapter 15: Class Hierarchies, Section 6: Free Store,
Subsection 2: Virtual constructors, pages 424-5.


Thanks for the refence; I've re-read it. I think he could declare new_expr
as a static member function. Then it could be used without an existing
object; esentially using the same principle as a simple function as
read_object above.

Ali

Oct 5 '05 #6
Ali Çehreli wrote:
E. Robert Tisdale wrote:
A virtual constructor is more "extensible ".
It is not more extensible than a function like read_object;
you can extend read_object any way we like.
Besides, their application are very different:
read_object returns a brand new object,
virtual constructor copies an existing object.
That's why I use virtual constructor in some of my copy constructors.
See Bjarne Stroustrup, "The C++ Programming Language: Third Edition",
Chapter 15: Class Hierarchies, Section 6: Free Store,
Subsection 2: Virtual constructors, pages 424-5.


Stoustrup's example shows a virtual "default constructor" (new_expr)
and a virtual "copy constructor" (clone) corresponding to
the actual constructors for class Expr.
Thanks for the refence; I've re-read it.
I think he could declare new_expr as a static member function.
Then it could be used without an existing object;
esentially using the same principle
as a simple function as read_object above.


That means that the base class would need to know about
all of the derived types which are, generally, unknown
when the base class is implemented.
Oct 6 '05 #7
On Wed, 05 Oct 2005 09:03:33 -0700, "E. Robert Tisdale"
<E.************ **@jpl.nasa.gov > wrote:
pmizzi wrote:
When I compile my program with the -ansi -Wall -pedantic flags,
I get this warning: `class vechile' has virtual functions
but non-virtual destructor,
It's a warning. Ignore it.


Famous last words. Warnings should be dealt with, or at least documented,
because they indicate an error-prone construct.

Destructors should almost always be declared virtual. Without virtual
destructors derived classes stand a good chance of not getting destroyed
correctly.
If you really need a virtual destructor,
you will need virtual constructors as well.
Virtual destructors and "virtual constructors" (vis-a-vis Stroustroup) solve
very different problems. Don't confuse them with each other.
No function should ever delete an object
that was allocated by the calling function and,
in C++, it is poor programming practice
to require the calling program
to explicitly delete an object through a pointer
returned by a function that allocated the object.


Nonsense. std::auto_ptr uses that idiom.

There are situations where an Orchestrator may construct an object on the heap
derived from some base class, then passes a reference to that object on the
heap to a helper object as a reference to the base class. The helper object
then "owns" and manages that object, and will destruct it on its own schedule.

There's nothing wrong with that pattern.

-dr
Oct 6 '05 #8
In message <di*********@nn tp1.jpl.nasa.go v>, E. Robert Tisdale
<E.************ **@jpl.nasa.gov > writes
Ali Çehreli wrote:
E. Robert Tisdale wrote:
If you really need a virtual destructor,
you will need virtual constructors as well. Not at all. Using a function to make the decision on what object to
construct and to return a base object pointer is very common:
Base* read_object(/* ... */) {
/* ... */
return some_condition? new Derived1: new Derived2;
}
/* ... */
Base* base = read_object(/* ... */);


But it isn't good programming practice in C++.
Your program already knows about types Derived1 and Derived2
so you might as well use them in the calling program.


So virtual functions are a waste of time. You heard it here first,
folks!

A virtual constructor is more "extensible ".
See Bjarne Stroustrup, "The C++ Programming Language: Third Edition",
Chapter 15: Class Hierarchies, Section 6: Free Store,
Subsection 2: Virtual constructors, pages 424-5.


--
Richard Herring
Oct 6 '05 #9
In message <di**********@n ntp1.jpl.nasa.g ov>, E. Robert Tisdale
<E.************ **@jpl.nasa.gov > writes
pmizzi wrote:
When I compile my program with the -ansi -Wall -pedantic flags,
I get this warning: `class vechile' has virtual functions
but non-virtual destructor,
It's a warning. Ignore it.
and the same with my sub-classes.
But, when I add a virtual destructor like this:
"virtual ~vechile", I get this error:

Undefined first referenced
symbol in file
vtable for vechile /var/tmp//ccC9yD6Z.o
ld: fatal: Symbol referencing errors. No output written to
a.out
collect2: ld returned 1 exit status
Can anyone help me?


Don't define a virtual destructor if you don't need one.
If you really need a virtual destructor,
you will need virtual constructors as well.


Nonsense. They aren't paired requirements.
No function should ever delete an object
that was allocated by the calling function
ITYM "programs using pointers need a consistent, well-defined ownership
model"
and,
in C++, it is poor programming practice
to require the calling program
to explicitly delete an object through a pointer
returned by a function that allocated the object.


If the caller doesn't delete the object, what does, and how would it
obviate the need for a virtual dtor?

You've just condemned many kinds of smart pointer, garbage collection,
factory patterns, and much more, as "poor programming practice."

Personally I shall continue to use them whenever it's appropriate.

--
Richard Herring
Oct 6 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
10501
by: Stub | last post by:
Please answer my questions below - thanks! 1. Why "Derived constructor" is called but "Derived destructor" not in Case 1 since object B is new'ed from Derived class? 2. Why "Derived destructor" is called in Case 2 since only ~base() becomes "virtual" and ~Derived() is still non-virtual? 3. Does Case 3 show that we don't need any virtual...
39
736
by: Ele | last post by:
Is it correct to say that Whenever a class has a virtual member function, define its destructor as "virtual"? Can a destructor as "pure virtual"? When is it needed to do so? For an interface, Interf: class Interf { public:
11
4344
by: santosh | last post by:
Hello, I was going through the Marshal Cline's C++ FAQ-Lite. I have a doubt regarding section 33.10. Here he is declaring a pure virtual destructor in the base class. And again defining it inline. Like this.
37
4139
by: WittyGuy | last post by:
Hi, I wonder the necessity of constructor and destructor in a Abstract Class? Is it really needed? ? Wg http://www.gotw.ca/resources/clcm.htm for info about ]
4
8427
by: Tony Johansson | last post by:
Hello Experts!! Assume I have a base class called animal. I want this class to be abstract so I make the destructor pure virtual by having this statement. virtual ~Animal() = 0; Destructor will never be inherited. Now to my question why do I have to give a body {} at least the empty body to the pure virtual destructor.
7
3080
by: eric | last post by:
hello i'm confused by an example in the book "Effective C++ Third Edition" and would be grateful for some help. here's the code: class Person { public: Person(); virtual ~Person(); // see item 7 for why this is virtual ...
7
1988
by: sam | last post by:
Hi, See when i reading a sourcecode of a program, I read that the constructor is ordinary and after that the programmer has written virtual destructor for that constructor . Why we use the virtual destructor whats the use of it? the code is like this: Network(int input,int output); Network(&Network); virtual ~Network();
3
1899
by: GAURAV AGRAWAL | last post by:
Hi Guys, Can someone please explain me why this is happening #include<iostream> using namespace std; class a { public: int a1; // If I remove this it'll work fine
7
7334
by: Tonni Tielens | last post by:
I'm trying to create a pure virtual class describing an interface. Normally, when I do this I make the destructor pure virtual so that, even if there are no members in the class, it cannot be instantiated. The difference now is that I'm making a generic interface with template arguments. Template classes should be defined in the header...
0
8312
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7920
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
8183
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
6569
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
1
5685
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
5366
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3809
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
1
2312
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
0
1147
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.