Thread: How do I avoid class destructor definition if class constructor is overloaded?

  1. #1
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827

    Question How do I avoid class destructor definition if class constructor is overloaded?

    How do I avoid class destructor definition if class constructor is overloaded?
    I am using a default constructor and a constructor with two arguments.

    When I create an object of the class with no arguments, using the default constructor, I want to avoid the class destructor because it causes a "Program received signal SIGSEGV, Segmentation fault." message when I debug (even though it compiles fine) because in the destructor I call a function which returns the value returned by the ifstream object filestreamInObject->is_open() function, and "filestreamInObject" is not created in the default constructor.
    Last edited by Programmer_P; 05-31-2010 at 01:35 PM.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    If you need to write a destructor, then you should write it such that it correctly destroys the object, regardless of how the object was validly constructed or modified.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827
    Quote Originally Posted by laserlight View Post
    If you need to write a destructor, then you should write it such that it correctly destroys the object, regardless of how the object was validly constructed or modified.
    The thing is, in the destructor, I wish to close the file opened in the constructor, before I delete the ifstream object "filestreamInObject". I do this by calling up "isFileOpen" which is a member function of my class which returns the value of the is_open function of my ifstream object, before attempting to close the file.

    EDIT: Nevermind. I'll just call ifstream::is_open() directly from my destructor. I don't why I didn't think of that before...
    Last edited by Programmer_P; 05-31-2010 at 01:42 PM.

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    ifilestreams and ofilestreams are closed by their destructors - whatever you're doing, keep that in mind.

  5. #5
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    It's not clear what you are asking, and even if you think you have it solved, you might still be doing the wrong thing and leaving yourself open to more bugs a little later on. Can you please post some code to illustrate your question?

    It sounds like you have a pointer to an ifstream as a member. Having a pointer to an ifstream as a member is most often the wrong thing to do. Normally one would just have an instance of an ifstream as the member, in which case you would most likely not even need a destructor.

    Is this advice sounding oddly familiar?
    Seriously, you need to have a pretty compelling reason to use a raw pointer to anything, as a member of a class in properly written C++ code.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  6. #6
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827
    Quote Originally Posted by iMalc View Post
    It's not clear what you are asking, and even if you think you have it solved, you might still be doing the wrong thing and leaving yourself open to more bugs a little later on. Can you please post some code to illustrate your question?

    It sounds like you have a pointer to an ifstream as a member. Having a pointer to an ifstream as a member is most often the wrong thing to do. Normally one would just have an instance of an ifstream as the member, in which case you would most likely not even need a destructor.
    Yes, that is correct. I'm using a pointer, which I create a 'new' ifstream object from in the constructor, because I need to access various functions of the same object from different functions of my class.
    Is this advice sounding oddly familiar?
    Seriously, you need to have a pretty compelling reason to use a raw pointer to anything, as a member of a class in properly written C++ code.
    Yeah, it sounds vaguely familiar...
    But I still think I have a pretty good reason to use a pointer instead of an ifstream instance.

    I'll post some example code in a minute...

  7. #7
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827
    Oh, and I need to mention I ended up commenting out my destructor, because I copied its code to a cleanUp() function which I call from the object of my class which uses the argument constructor, after I get done with it. That way there is no conflict with the object that uses the default (no-argument) constructor.

    Might not be the best solution, but it works...

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Programmer_P
    But I still think I have a pretty good reason to use a pointer instead of an ifstream instance.
    Why do you think so?

    Note that std::istream objects, and thus std::ifstream objects, are not copyable. This has ramifications on the copy behaviour of the objects of your class.

    Quote Originally Posted by Programmer_P
    Oh, and I need to mention I ended up commenting out my destructor, because I copied its code to a cleanUp() function which I call from the object of my class which uses the argument constructor, after I get done with it. That way there is no conflict with the object that uses the default (no-argument) constructor.
    No, you're doing it the wrong way. Now, you have just created a situation where you need to remember to call this cleanUp() function, even in the face of exceptions. Furthermore, you need to remember when not to call it. Complicated, no?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827
    Quote Originally Posted by laserlight View Post
    Why do you think so?

    Note that std::istream objects, and thus std::ifstream objects, are not copyable. This has ramifications on the copy behaviour of the objects of your class.
    That is fine, because I'm not trying to copy any ifstream object. I am using the same ifstream object created on the heap across multiple functions of my class.
    No, you're doing it the wrong way. Now, you have just created a situation where you need to remember to call this cleanUp() function, even in the face of exceptions. Furthermore, you need to remember when not to call it. Complicated, no?
    Yeah...I realize that. However, seeing as my class is not abstract enough to re-use anywhere, most likely, and I wrote it to solve a specific problem, and there are only two objects of this class which I create (one using the default constructor, and the other using the argument constructor), and I called the cleanup function on the argument constructor, and I am 100% positive that I did that right, I don't think its a problem...

  10. #10
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827
    Oh, and the object of my class that uses the default constructor, doesn't do anything with any ifstream object. All I'm using the default constructor object for is calling up the help() function of the class, which returns a string message detailing proper usage of the program.

  11. #11
    ...and never returned. StainedBlue's Avatar
    Join Date
    Aug 2009
    Posts
    168
    What I find confusing is if your class is handling file IO, why does the default constructor not do anything with the file IO pointer, while the other constructor does?

    This makes no sense.

    Also, avoiding the destructor because one of your constructors seg faults is not a good reason to avoid calling the destructor. If your class needs a destructor, it always needs one, not just in certain cases.
    goto( comeFrom() );

  12. #12
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827
    Quote Originally Posted by StainedBlue View Post
    What I find confusing is if your class is handling file IO, why does the default constructor not do anything with the file IO pointer, while the other constructor does?
    Because the default constructor is not there to do anything with files or anything related. Like I just mentioned, I create an object using the default constructor for the sole purpose of calling up a help() function of the class. That is all I use the default constructor for, so it doesn't need to do anything with filestreams.
    This makes no sense.
    Yes, it does, and I just explained it.
    Also, avoiding the destructor because one of your constructors seg faults is not a good reason to avoid calling the destructor. If your class needs a destructor, it always needs one, not just in certain cases.
    No, it doesn't. Not when I use the default constructor, because no objects are created by the default constructor. The argument constructor is the one that creates objects on the heap, hence the need for the destructor (now replaced with a "cleanUp()" function)...

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Programmer_P
    Yeah...I realize that. However, seeing as my class is not abstract enough to re-use anywhere, most likely, and I wrote it to solve a specific problem, and there are only two objects of this class which I create (one using the default constructor, and the other using the argument constructor), and I called the cleanup function on the argument constructor, and I am 100% positive that I did that right, I don't think its a problem...
    Well, it is your code, so it is your choice. In my opinion, this defect in your design is quite serious, even if you believe that the code is throw-away code. You would do well to document the problem very clearly so that the class really never ever gets reused without being fixed. Even then...

    Quote Originally Posted by Programmer_P
    That is fine, because I'm not trying to copy any ifstream object. I am using the same ifstream object created on the heap across multiple functions of my class.
    I think I understand your idea now: basically, this class is a sham. You would be better off just writing the whole thing procedurally, because that is essentially what you are doing. You are not thinking in terms of objects, and thus are not concerned with their lifetimes. The constructors do not conceptually construct objects of the class: they are just a means for you to be able to call functions via a particular syntax. The destructor does not conceptually destroy objects of the class: it is just fluff.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  14. #14
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827
    Quote Originally Posted by laserlight View Post
    Well, it is your code, so it is your choice. In my opinion, this defect in your design is quite serious, even if you believe that the code is throw-away code. You would do well to document the problem very clearly so that the class really never ever gets reused without being fixed. Even then...
    First of all, though I plan on sharing the code for the purpose of others being able to compile and use the program, I don't expect the class to ever be re-used for anything, though anyone is welcome to edit the source code if they want, of course.
    But the program is for a specific purpose (i.e. to get the string names of enum values), and the program will achieve that purpose and cleanup after itself. What more do I need out of the program?
    I think I understand your idea now: basically, this class is a sham.
    That is a matter of opinion...
    You would be better off just writing the whole thing procedurally, because that is essentially what you are doing.
    Another opinion...
    You are not thinking in terms of objects, and thus are not concerned with their lifetimes.
    Actually, I was thinking in terms of objects. I was thinking in terms of only two objects of the class, one using the default constructor, the other using the argument constructor. And the lifetimes of the objects of the class, in this case, are not all that important. I basically create them in int main(), use them for their intended purpose, then let them fall off the stack once they go out of scope.
    The constructors do not conceptually construct objects of the class: they are just a means for you to be able to call functions via a particular syntax.
    Correction: The default constructor doesn't, but the argument constructor does.
    The destructor does not conceptually destroy objects of the class: it is just fluff.
    Like already mentioned at least two times already, I no longer have a destructor. I have a cleanUp() function which is there to delete all "new" objects created in the argument constructor.

  15. #15
    ...and never returned. StainedBlue's Avatar
    Join Date
    Aug 2009
    Posts
    168
    Because the default constructor is not there to do anything with files or anything related. Like I just mentioned, I create an object using the default constructor for the sole purpose of calling up a help() function of the class. That is all I use the default constructor for, so it doesn't need to do anything with filestreams.
    Look, I'm just trying to give you helpful criticism. I'm sorry, the class makes no sense. If you're coming from a Java background, I can understand the need to put *everything* in a class, but it just doesn't make sense, and this is why...

    If I have a class called FileOps, it should encapsulate only what is necessary for file operations. It's constructor, private members, and member functions should deal with file operations. Nothing else.

    If a user needs "help", then that is a completely separate matter, and doesn't belong in the FileOps class. Obviously you understand what I'm telling you --look to the very problems that you're having with your constructors/destructor! It's right there in front of you.

    The design of your class simply makes no sense, period.
    goto( comeFrom() );

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Whats the best way to control a global class?
    By parad0x13 in forum C++ Programming
    Replies: 3
    Last Post: 11-12-2009, 05:17 PM
  2. deriving classes
    By l2u in forum C++ Programming
    Replies: 12
    Last Post: 01-15-2007, 05:01 PM
  3. Warnings, warnings, warnings?
    By spentdome in forum C Programming
    Replies: 25
    Last Post: 05-27-2002, 06:49 PM
  4. gcc problem
    By bjdea1 in forum Linux Programming
    Replies: 13
    Last Post: 04-29-2002, 06:51 PM
  5. Difficulty superclassing EDIT window class
    By cDir in forum Windows Programming
    Replies: 7
    Last Post: 02-21-2002, 05:06 PM