CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 29
  1. #1
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,867

    Are these c'tors legal or dangerous?

    I've just come across this code in a 3rd party library which seems otherwise very professionally written....

    Code:
    // Declaration
    class CMyClass
    {
    public:
    	CMyClass(void);
    	CMyClass(char* name);
    	virtual ~CMyClass(void);
    
    // Data
    private:
    	char* name;
    
    public:
    	char* GetName(void) { return name; }
    };
    
    
    // Constructor #1
    CMyClass::CMyClass(void)
    : name("Default name")
    {
    }
    
    
    // Constructor #2
    CMyClass::CMyClass(char* szName)
    : name(szName)
    {
    }
    The class seems to work but my question is whether or not these c'tors are dangerous. The member function CMyClass::GetName() successfully returns either the supplied name or the default name depending on which c'tor was used - but it worries me that no memory's been allocated anywhere.

    C'tor #2 makes reasonable sense. It's c'tor #1 that worries me. Is the string "Default name" guaranteed to exist for the duration of the object?
    Last edited by John E; October 28th, 2006 at 10:04 AM.
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  2. #2
    Join Date
    Jun 2002
    Location
    Moscow, Russia.
    Posts
    2,176

    Re: Are these c'tors legal or dangerous?

    Yes, it's guaranteed. It has static storage duration.
    However there are problems with this class.
    Code:
    CMyClass
     c1;
    char* str = c1.GetName();
    // is it OK to have "Default name" returned?
    
    char buf[10]="abc";
    CMyClass c2(buf);
    buf[0]='d';
    // now c2.GetName() returns "dbc";
    
    char buf2[10]="efg";
    CMyClass c3(buf2);
    c3.GetName()[0]='h';
    // now buf2 is "hfg"
    "Programs must be written for people to read, and only incidentally for machines to execute."

  3. #3
    Join Date
    Feb 2005
    Location
    Normandy in France
    Posts
    4,590

    Re: Are these c'tors legal or dangerous?

    Quote Originally Posted by John E
    The class seems to work but my question is whether or not these c'tors are dangerous. The member function CMyClass::GetName() successfully returns either the supplied name or the default name depending on which c'tor was used - but it worries me that no memory's been allocated anywhere.
    This class doesn't own this character pointer.
    I think it's not a very good idea, but if it's written in the class's documentation, it's not incorrect.
    The guy who invokes the constructor has to know that the lifetime of the data pointed-at by the pointer, have to be longer than the lifetime of the object.
    Here, I think it's not a particulary good idea... A name is something that should be owned by the class.

    C'tor #2 makes reasonable sense. It's c'tor #1 that worries me. Is the string "Default name" guaranteed to exist for the duration of the object?
    The string "Default name" is guaranteed to exist from the start of the program until the end. No problem.

    There are ugly things here:
    • Having a default name is not a great idea, and... Since it's a default parameter, it should have been treated as a default parameter, not with an overload of the constructor.
    • This program seems const unaware... This name should probably be a std::string or a const char*
    • The destructor is very probably uselessly virtual since there is no other virtual function.
    "inherit to be reused by code that uses the base class, not to reuse base class code", Sutter and Alexandrescu, C++ Coding Standards.
    Club of lovers of the C++ typecasts cute syntax: Only recorded member.

    Out of memory happens! Handle it properly!
    Say no to g_new()!

  4. #4
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    Re: Are these c'tors legal or dangerous?

    Yep. The second ctor is the one that would worry me - no guarantee that the pointed-to string exists for the lifetime of the object. A std::string member would be much safer.

    Also, the use of "(void)" in a C++ program is a bit odd. Fine for C, but empty parentheses in C++ mean "no arguments". Putting void in there is pointless and ugly.
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  5. #5
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,867

    Re: Are these c'tors legal or dangerous?

    So let's suppose that I now have a second class which contains a member pointer to the original class (CMyClass* m_pMyClass). Am I right in thinking that this would work:-
    Code:
    CMyOtherClass::CMyOtherClass()
    {
    	m_pMyClass = new CMyClass("A suitable name");
    }
    
    
    CMyOtherClass::~CMyOtherClass()
    {
    	delete m_pMyClass;
    }
    
    
    CMyOtherClass::SomeFunc()
    {
    char buf[32];
    
    	strcpy(buf, m_pMyClass->GetName();
    }
    whereas this would not work:-
    Code:
    CMyOtherClass::CMyOtherClass()
    {
    char buf[32] = "A suitable name"
    
    	m_pMyClass = new CMyClass(buf);
    }
    
    
    CMyOtherClass::~CMyOtherClass()
    {
    	delete m_pMyClass;
    }
    
    
    CMyOtherClass::SomeFunc()
    {
    char buf[32];
    
    	strcpy(buf, m_pMyClass->GetName();
    }
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  6. #6
    Join Date
    Mar 2002
    Location
    California
    Posts
    1,582

    Re: Are these c'tors legal or dangerous?

    but my question is whether or not these c'tors are dangerous.
    It certainly violates Meyer's Effective C++ Item 18:

    "Make interfaces easy to use correctly and hard to use incorrectly"

    Jeff

  7. #7
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,867

    Re: Are these c'tors legal or dangerous?

    Yes - I'm starting to realise that this class will work correctly if it's always constructed using a string literal (whether default or not) but it would be risky to use with a non-const string. Is that right?

    I might modify it to use std::string instead of char* name;
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  8. #8
    Join Date
    Mar 2002
    Location
    California
    Posts
    1,582

    Re: Are these c'tors legal or dangerous?

    Quote Originally Posted by John E
    Yes - I'm starting to realise that this class will work correctly if it's always constructed using a string literal (whether default or not) but it would be risky to use with a non-const string. Is that right?
    More precisely, the lifetime of the string must exceed the lifetime of the class holding it.

    Quote Originally Posted by John E
    I might modify it to use std::string instead of char* name;
    That would be a huge improvement in both safety and correctness.

    Jeff

  9. #9
    Join Date
    Aug 2002
    Location
    Madrid
    Posts
    4,588

    Re: Are these c'tors legal or dangerous?

    In your post #6, you are right. The second code leads to undefined results. And basically it would be dangerous to use the class with any string that's not a literal, because you'll have to watch the lifetime of the string vs the lifetime of the object.

    I might modify it to use std::string instead of char* name;
    By all means. There shouldn't be any problem because the class didn't own the storage in the first place.
    Get this small utility to do basic syntax highlighting in vBulletin forums (like Codeguru) easily.
    Supports C++ and VB out of the box, but can be configured for other languages.

  10. #10
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,867

    Re: Are these c'tors legal or dangerous?

    Just looking through the rest of the 3rd party code I can see that objects of this type are always being created using a string literal but I'll change the class to use std::string anyway. I'm confused by this comment from SuperKoko:-
    Quote Originally Posted by SuperKoko
    The destructor is very probably uselessly virtual since there is no other virtual function.
    Here's what I always thought to be the received wisdom with regard to virtual d'tors (i.e. always make the base class d'tor virtual).
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  11. #11
    Join Date
    Aug 2002
    Location
    Madrid
    Posts
    4,588

    Re: Are these c'tors legal or dangerous?

    Yes, as soon as you use the class as a base in a hierarchy you should have a virtual destructor. Whether or not the class has virtual functions doesn't matter. (Now whether it's good to have a class hierarchy without virtual functions is another story )
    Get this small utility to do basic syntax highlighting in vBulletin forums (like Codeguru) easily.
    Supports C++ and VB out of the box, but can be configured for other languages.

  12. #12
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,867

    Re: Are these c'tors legal or dangerous?

    Suppose you have a 3 class hierarchy - base.... derived1 (derived from base) and derived2 (derived from derived1). Should you put virtual functions in base and derived1 or is it only necessary in the base class?
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  13. #13
    Join Date
    Jun 2002
    Location
    Moscow, Russia.
    Posts
    2,176

    Re: Are these c'tors legal or dangerous?

    Quote Originally Posted by Yves M
    Yes, as soon as you use the class as a base in a hierarchy you should have a virtual destructor. Whether or not the class has virtual functions doesn't matter.
    There're many final classes.
    "Programs must be written for people to read, and only incidentally for machines to execute."

  14. #14
    Join Date
    Aug 2002
    Location
    Madrid
    Posts
    4,588

    Re: Are these c'tors legal or dangerous?

    Quote Originally Posted by RoboTact
    There're many final classes.
    Hum, there are no final classes in C++. The language doesn't support it. But anyways, the virtual destructor only applies to classes used "as a base in a hierarchy" as I said previously.

    Suppose you have a 3 class hierarchy - base.... derived1 (derived from base) and derived2 (derived from derived1). Should you put virtual functions in base and derived1 or is it only necessary in the base class?
    If you don't override virtual functions then the whole concept doesn't make sense. So if you only have virtual functions in the base class, it's not really useful, because you can't actually use polymorphism (i.e. p->somefunc() will always be determined at compile time if you don't override virtual functions). So if you override the virtual function in base and derived1, it makes more sense.
    Get this small utility to do basic syntax highlighting in vBulletin forums (like Codeguru) easily.
    Supports C++ and VB out of the box, but can be configured for other languages.

  15. #15
    Join Date
    Feb 2005
    Location
    Normandy in France
    Posts
    4,590

    Re: Are these c'tors legal or dangerous?

    Quote Originally Posted by Yves M
    Yes, as soon as you use the class as a base in a hierarchy you should have a virtual destructor. Whether or not the class has virtual functions doesn't matter. (Now whether it's good to have a class hierarchy without virtual functions is another story )
    virtual destructors should be used when the object might be destroyed through a pointer to Base.
    I highly doubt you'll in your right mind, destroy an object through a pointer to a base class having no virtual function.
    Well, you can be paranoid and know that you're dumb and destroy with wrong pointers your objects... But in that case, you'll want to add a virtual destructor to the void type... Unfortunately, that's impossible.

    Anyway, since concrete classes are rarely derived from... If you've a class designed to be derived, you can define the destructor as protected.

    There is nothing fundamentally wrong with making all destructors virtual... It's not more wrong than making all non-static member functions virtual... But you must know that there are speed and space overheads, and your intent may not be clear for a normal person who would read your code.
    "inherit to be reused by code that uses the base class, not to reuse base class code", Sutter and Alexandrescu, C++ Coding Standards.
    Club of lovers of the C++ typecasts cute syntax: Only recorded member.

    Out of memory happens! Handle it properly!
    Say no to g_new()!

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured