CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6
  1. #1
    Join Date
    Aug 2002
    Posts
    78

    Operator (cast) override vs. static_cast et al.

    Ok, so I have a class that overrides the (const char *) operator. This override returns a C string that is not the same as the pointer to the class.


    Which, if any, of these calls will invoke the overridden operator, and which will merely reinterpret the class' pointer?

    reinterpret_cast<const char *>
    static_cast<const char *>
    dynamic_cast<const char *>


    This is a serious issue because people are starting to blindly clean up Lint problems, one of which is whining about using old style C casts. For now we are avoiding correcting that warning.

  2. #2
    Join Date
    Aug 2002
    Location
    Madrid
    Posts
    4,588
    With a little help from Andreas' FAQ item on casting
    • reinterpret_cast<const char *>
      FAQ
      This operator can cast pointers between non-related classed. The operation results is a simple binary copy of the value from a pointer to the other. The content pointed does not pass any kind of check nor transformation between types.
      This means that reinterpret_cast will NOT result in calling the operator if you call it on a pointer to your class.
    • static_cast<const char *>
      FAQ
      Applied to pointers to classes, that is to say that it allows to cast a pointer of a derived class to its base class (this is a valid conversion that can be implicitly performed) and can also perform the inverse: cast a base class to its derivated class.
      This only works for related types or classes. In this case, const char * and your class name are not related, so it won't work.
    • dynamic_cast<const char *>
      This only applies to classes, so the statement doesn't even make sense.

    This means that in effect the only thing that you *can* use is the implicit casting that is made when your target is a const char *. If you need to make it explicit, then don't override the operator const char *, but rather use a function to return it, just the same way as std::string does it with c_str().
    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.

  3. #3
    Join Date
    Apr 1999
    Posts
    27,449
    I agree with Yves: replace the cast with a function call, especially one so common as "const char *".

    Not only will you clean up your lint warnings, you will also clean up any parts of the code that may not do what you think it will do.

    When you have casting operators implemented such as const char *, the compiler may (without you knowing) use the implicit casting to call functions without you even knowing they're being called. So either you get a compiler error saying your call is "ambiguous" and it "matches x overloads", or it does match one function but it isn't the one you expected when you run the program. These errors are almost impossible to spot unless you use a debugger and see what function(s) are using your overloaded casting operator.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; February 11th, 2004 at 11:46 AM.

  4. #4
    Join Date
    Aug 2002
    Posts
    78
    Unfortunately making a function call is not viable. This is a very large project, and that is in a part of code shared with other project. Literally, not figuratively, hundreds of files would be touched by this change, even if it weren't in shared code, just for my project.

    So the proper answer is that none of the C++-style casts will call the overridden casting operator.

    Lint programs need to get smarter still to check if the cast is overridden and will do something besides "old style" activities.

  5. #5
    Join Date
    Nov 2002
    Location
    Foggy California
    Posts
    1,245
    I believe that static_cast<> will work if it acts on a class or class reference, but not on a pointer to a class. For example:

    Code:
    #include <string>
    #include <iostream>
    
    using namespace std;
    
    class MyString
    {
    public:
        string s;
    
        operator const char*()
        {
            return s.c_str();
        }
    };
    
    int main()
    {
        MyString s;
        s.s.append("Hi there");
    
        cout << s.s << endl;
        cout << static_cast<const char*>(s) << endl;
        return 0;
    }
    This code compiled and ran correctly for me. This might be a non-conformant part of my compiler (VC.NET 2003) -- I am not sure. I believe though that static_cast<> will work in this situation. Mind you this can quickly lead to problems coding though. There will be problems if someone attempts to pass a pointer rather than a class or reference!

    However, I also believe that the more important thing would be to make code clear and less prone to mistakes whenever possible. The best solution would be to take Yves' suggestion and implement a c_str()-like function.

    - Kevin

  6. #6
    Join Date
    Aug 2002
    Location
    Madrid
    Posts
    4,588
    Originally posted by KevinHall
    I believe that static_cast<> will work if it acts on a class or class reference, but not on a pointer to a class.
    Yes, you are right. I've not been careful enough.
    MSDN being a bit helpful here
    The static_cast operator can also be used to perform any implicit conversion, including standard conversions and user-defined conversions.
    However, there is not much benefit (apart from maybe making things a bit clearer), since it has to be implicitly convertible anyways, so leaving out the cast should also work.
    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.

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