Thread: Can you please tell me why one method is better than the other ( code inside!)?

  1. #1
    Registered User
    Join Date
    Aug 2007
    Posts
    2

    Can you please tell me why one method is better than the other ( code inside!)?

    Hi,
    Can someone please tell me what is the advantage of method one over method two?

    Thanks
    Shahram

    Code:
    #include <iostream>
    #include "boost/shared_ptr.hpp"
    
    
    
    //
    // method 1
    //
    class base{
    protected:
      class inner{
      public:
              virtual int f()=0;
      };
      boost::shared_ptr<base::inner> ptr_inner;
      base(boost::shared_ptr<base::inner> new_inner):ptr_inner(new_inner){;};
      public:  
      int f(){return(ptr_inner->f());};
    };
    class drived:public base{
    private:     
             class inner:public base::inner{
                         int f(){return(1);};
             };
    public:
             drived(): base(boost::shared_ptr<base::inner>(new drived::inner)){};
    };
    
    
    
    //
    // method 2
    //
    
    
    class base_prime{
    public:                 
      virtual int f()=0;
    };
    
    class drived_prime:public base_prime{
    public:
         int f(){return(1);};               
    };
    
    
    
    
    
    int main(int argc, char *argv[])
    {
    
        base b = drived();
        base_prime b_prime = drived_prime();
        boost::shared_ptr<base_prime> b_prime(new drived_prime());
        std::cout << b.f()<<std::endl;
        std::cout << b_prime->f()<<std::endl;
    
    
    
            return (0);
    }

  2. #2
    Registered User
    Join Date
    Feb 2006
    Posts
    312
    Who said that either method has any 'advantage' over the other?

    perhaps you could explain what you are attempting to do, and why you think one way may or may not be better

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I'll start the discussion by saying that method 2 is better - it's much simpler, and "Keep it simple" is a good way to work - things tend to get complex enough when you work on them for a while, without making it MORE complex to begin with.

    Of course, it does depend on what your end goal is.

    --
    Mats

  4. #4
    Registered User
    Join Date
    Aug 2007
    Posts
    2
    Thanks for the replies. the code I posted is a simple version of a large free source C++ libary. Every time there is a similar set of functions, they use the method 1. I myself would have used method 2 for the same obvious reasons. But I am aware there were probably reasons why they used method 2.

    here is the extract of the code

    Code:
    //
    // daycounter.hpp (extract)
    //
    
    #ifndef quantlib_day_counter_hpp
    #define quantlib_day_counter_hpp
    
    #include <ql/time/date.hpp>
    #include <ql/errors.hpp>
    
    namespace QuantLib {
    
        class DayCounter {
          protected:
            class Impl {
              public:
                virtual ~Impl() {}
                virtual std::string name() const = 0;
                //! to be overloaded by more complex day counters
                virtual Time yearFraction(const Date& d1,
                                          const Date& d2,
                                          const Date& refPeriodStart,
                                          const Date& refPeriodEnd) const = 0;
            };
            boost::shared_ptr<Impl> impl_;
            DayCounter(const boost::shared_ptr<Impl>& impl) : impl_(impl) {}
          public:
            DayCounter() {}
            Time yearFraction(const Date&, const Date&,
                              const Date& refPeriodStart = Date(),
                              const Date& refPeriodEnd = Date()) const;
        };
    
    
        inline Time DayCounter::yearFraction(const Date& d1, const Date& d2,
            const Date& refPeriodStart, const Date& refPeriodEnd) const {
                QL_REQUIRE(impl_, "no implementation provided");
                return impl_->yearFraction(d1,d2,refPeriodStart,refPeriodEnd);
        }
    }
    
    #endif // end of file
    
    
    
    
    //
    // actual360.hpp (extract)
    //
    
    
    #ifndef quantlib_actual360_day_counter_h
    #define quantlib_actual360_day_counter_h
    
    #include <ql/daycounter.hpp>
    
    namespace QuantLib {
    
        //! Actual/360 day count convention
    
     class Actual360 : public DayCounter {
          private:
            class Impl : public DayCounter::Impl {
              public:
                Time yearFraction(const Date& d1,
                                  const Date& d2,
                                  const Date&,
                                  const Date&) const {
                    return dayCount(d1,d2)/360.0;
                }
            };
          public:
            Actual360()
            : DayCounter(boost::shared_ptr<DayCounter::Impl>(
                                                          new Actual360::Impl)) {}
        };
    
    }
    
    #endif // end of file

  5. #5
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Often separate Impl inner classes are used to satisfy the PIMPL idiom, although that doesn't seem to apply exactly here.

    Using a shared_ptr to hold an impl would mean that copying acts like copying in Java. If you make a copy of an object both copies would share the same implementation. When copying a normal C++ class the two copies usually have separate data.

    However, in this case I don't see any data members, so there is no state and copying wouldn't matter. Perhaps that is how they implement all classes in case state variables are required later.

  6. #6
    Registered User
    Join Date
    May 2006
    Posts
    630
    Quote Originally Posted by Daved View Post
    Often separate Impl inner classes are used to satisfy the PIMPL idiom,
    Can it be useful to learn this 'PIMPL' approach? Do you ever find it useful?

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    I have used it in the following scenario. Our app has a bunch of core classes that model a bunch of important objects. On several occasions I have had to create a utility class that operates on data from those core classes. This utility mines data from the core classes and reports on what it finds.

    The utility's output is basically just strings and integers. None of the output depends on the core classes. This utility will be used in several different dlls and libraries. I don't want the code in these other libraries to be dependent on the core classes in any way. All they should need to know is how to run the utility and understand the output.

    However, the utility needs the core classes for its implementation. It needs member variables that are from the core classes. It needs to pass core class instances around to other implementation functions. It needs to do a lot of stuff that requires thet it #include the headers for those core classes.

    If I #included the headers for those core classes in the header of the utility class, then all the libraries that use the utility would suddenly be dependent on the core classes. I don't want that (and in some situations probably can't have it due to potential circular dependencies). So I use a PIMPL. Then, I don't have to #include or mention any of the core classes in the header file (except one forward declaration). All the core class #includes are done in the source file where the Impl class is defined.

    The dependencies of the implementation of the utility class are hidden from the libraries that need to use it.

    As far as whether it is useful to learn, I'm sure it is useful to add it to your repertoire. I think some libraries use it religiously, so if only for understanding I think it would be helpful. I don't know if you'd actually use it because I don't know how complicated your projects are and how complicated the dependencies can be.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. class method inside cout fails
    By atapi103 in forum C++ Programming
    Replies: 2
    Last Post: 08-24-2003, 11:35 PM
  2. Seems like correct code, but results are not right...
    By OmniMirror in forum C Programming
    Replies: 4
    Last Post: 02-13-2003, 01:33 PM
  3. What did i do wrong? Code inside
    By The Rookie in forum C Programming
    Replies: 2
    Last Post: 05-18-2002, 08:14 AM
  4. How-To: Load Pictures in MFC. Code Inside.
    By Xei in forum C++ Programming
    Replies: 1
    Last Post: 05-16-2002, 09:17 PM
  5. Replies: 4
    Last Post: 01-16-2002, 12:04 AM