Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 255975
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 11, 20262026-05-11T21:58:32+00:00 2026-05-11T21:58:32+00:00

Suppose we have a (toy) C++ class such as the following: class Foo {

  • 0

Suppose we have a (toy) C++ class such as the following:

class Foo {
    public:
        Foo();
    private:
        int t;
};

Since no destructor is defined, a C++ compiler should create one automatically for class Foo. If the destructor does not need to clean up any dynamically allocated memory (that is, we could reasonably rely on the destructor the compiler gives us), will defining an empty destructor, ie.

Foo::~Foo() { }

do the same thing as the compiler-generated one? What about an empty constructor — that is, Foo::Foo() { }?

If there are differences, where do they exist? If not, is one method preferred over the other?

  • 1 1 Answer
  • 3 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-11T21:58:32+00:00Added an answer on May 11, 2026 at 9:58 pm

    It will do the same thing (nothing, in essence). But it’s not the same as if you didn’t write it. Because writing the destructor will require a working base-class destructor. If the base class destructor is private or if there is any other reason it can’t be invoked, then your program is faulty. Consider this

    struct A { private: ~A(); };
    struct B : A { }; 
    

    That is OK, as long as your don’t require to destruct an object of type B (and thus, implicitly of type A) – like if you never call delete on a dynamically created object, or you never create an object of it in the first place. If you do, then the compiler will display an appropriate diagnostic. Now if you provide one explicitly

    struct A { private: ~A(); };
    struct B : A { ~B() { /* ... */ } }; 
    

    That one will try to implicitly call the destructor of the base-class, and will cause a diagnostic already at definition time of ~B.

    There is another difference that centers around the definition of the destructor and implicit calls to member destructors. Consider this smart pointer member

    struct C;
    struct A {
        auto_ptr<C> a;
        A();
    };
    

    Let’s assume the object of type C is created in the definition of A’s constructor in the .cpp file, which also contains the definition of struct C. Now, if you use struct A, and require destruction of an A object, the compiler will provide an implicit definition of the destructor, just like in the case above. That destructor will also implicitly call the destructor of the auto_ptr object. And that will delete the pointer it holds, that points to the C object – without knowing the definition of C! That appeared in the .cpp file where struct A’s constructor is defined.

    This actually is a common problem in implementing the pimpl idiom. The solution here is to add a destructor and provide an empty definition of it in the .cpp file, where the struct C is defined. At the time it invokes the destructor of its member, it will then know the definition of struct C, and can correctly call its destructor.

    struct C;
    struct A {
        auto_ptr<C> a;
        A();
        ~A(); // defined as ~A() { } in .cpp file, too
    };
    

    Note that boost::shared_ptr does not have that problem: It instead requires a complete type when its constructor is invoked in certain ways.

    Another point where it makes a difference in current C++ is when you want to use memset and friends on such an object that has a user declared destructor. Such types are not PODs anymore (plain old data), and these are not allowed to be bit-copied. Note that this restriction isn’t really needed – and the next C++ version has improved the situation on this, so that it allows you to still bit-copy such types, as long as other more important changes are not made.


    Since you asked for constructors: Well, for these much the same things are true. Note that constructors also contain implicit calls to destructors. On things like auto_ptr, these calls (even if not actually done at runtime – the pure possibility already matters here) will do the same harm as for destructors, and happen when something in the constructor throws – the compiler is then required to call the destructor of the members. This answer makes some use of implicit definition of default constructors.

    Also, the same is true for visibility and PODness that i said about the destructor above.

    There is one important difference regarding initialization. If you put a user declared constructor, your type does not receive value initialization of members anymore, and it is up to your constructor to do any initialization that’s needed. Example:

    struct A {
        int a;
    };
    
    struct B {
        int b;
        B() { }
    };
    

    In this case, the following is always true

    assert(A().a == 0);
    

    While the following is undefined behavior, because b was never initialized (your constructor omitted that). The value may be zero, but may aswell be any other weird value. Trying to read from such an uninitialized object causes undefined behavior.

    assert(B().b == 0);
    

    This is also true for using this syntax in new, like new A() (note the parentheses at the end – if they are omitted value initialization is not done, and since there is no user declared constructor that could initialize it, a will be left uninitialized).

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Suppose I have: public class foobar { public int lorem; public int ipsum; }
Suppose I have a macro defined as this: #define FOO(x,y) \ do { int
Suppose you have the following object hierarchy: class Vehicle { public: virtual ~Vehicle() {}
Suppose you have the following Generic class heirarchy: public abstract class GenericBase<T> { T
Suppose I have the following HTML: <form id=myform> <input type='checkbox' name='foo[]'/> Check 1<br/> <input
Suppose I have a grid of squared defined like so in a class: Square
Suppose we have the following: data Foo x from_list :: [x] -> Foo x
Suppose I have the following table: PERSON : ID INT NAME STRING LASTNAME STRING
suppose I have the following serial C: int add(int* a, int* b, int n)
Suppose I have some code like this: public string SomeMethod(int Parameter) { string TheString

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.