Please answer the following c++ questions

Document Sample
Please answer the following c++ questions Powered By Docstoc
					Please answer the following c++ questions. Do not simply answer yes/no.
Always explain your assumptions and reasoning.


1. memset is sometimes used to initialize data in a constructor like the example below.
   What is the benefit of initializing this way? Does it work in this example? Does it work
   in general ? Is it a good idea in general?

        class A {
        public:
           A();
        private:
           int a;
           float f;
           char str[35];
           long *lp;
        };

        A::A()
        {
           memset(this, 0, sizeof(*this));
        }

     Solution:
         To use memset this way is fast to initialize the memory filled with the same contents, which
is int 0 in this situation. Also, the other effect is that the object is created on the heap instead of the
stack.
         To make the code to compile, one may have to cast pointer this with void*. Meanwhile, this
is C style programming and does not consider the inheritance and function overriding in C++. The
general idea will work in this case, but in a broader scope, when A is a class derived from other
classes, the member data derived from the base class but not explicitly declared in A will not be
included in the object instance creased this way. Also, if the virtual function is created, the vptr will
also be written to the universal value (0 in this case), and the information will be lost.
         In general I do not think this is a good idea. First of all, it blocks the possibility of
inheritance and virtual function. Second, it always makes people nervous to create object on the
heap. The pointer have to be freeed after usage to prevent memory leak, and if an exception is
thrown before, the pointer is lost.

2. Your task is to implement the Reduce function using templates. The Reduce fn applies
   a function of two arguments cumulatively to the items of an STL container, from begin()
   to end(), so as to reduce the sequence to a single value. For example, Reduce(<list
   containing 1,2,3,4,5>, std::plus<int>()) should calculate ((((1+2)+3)+4)+5).

        class NotEnoughElements {};

        template <typename Container, typename Function>
        typename Container::value_type
        Reduce(const Container& c, Function fn) throw (NotEnoughElements)
        {
              //FILL OUT
             //get the size of the container
             int size=c.size();
             //the length must be greater or equal to 2
             if(size<2) throw new NotEnoughElements();


             Container::iterator bitr=c.begin();
             Container::iterator itr=c.begin();
             itr++;

            //call the std::plus function to add the first element and the next
element, then put the results into the first element.
            while(itr!=c.end()){
                  *bitr=fn(*bitr, *itr);
                  itr++;
            }

             //delete the elements in the list except the first
             itr=c.begin();
             erase(++itr, c.end());

      }

3. Write a C++ program that would find and print the first longest ascending or
   descending subsequence for a vector of integers. For example, given a vector with

      4, 2, 1, 2, 3, 4, 3, 5, 1, 2, 4, 6, 5

   the program would find the underlined subsequence and print it.


      #include<iostream>

      void findFirstLongest(int* list, int length)
      {

           int startPoint=0;//record the startpoint
           int longest=0;//the longest length in descending
      subsequence
           int longestPosition=-1;//the starting position of the
      longest sequence
           int i;//temp int
           bool longer;//check if the current is longer than that
      stored.

     //check the length of the descending subsequence from every
start point. The next start point will be the previous one plus
the length of the subsequence.
     for(startPoint=0;startPoint<length;startPoint+=i)
     {
          i=1;//set subsequence length to 1, for current
startpoint
          //Measure the length of the subsequence from startpoint
          while(list[startPoint+i-1]==list[startPoint+i]+1)
               i++;

               //is this longer than the longest stored?
               longer=(i>longest);

               longest=longer?i:longest;
               longestPosition=longer?startPoint:longestPosition;
       }

     //check if any error in the previous steps, possibly will be
alright.
     if(longestPosition>0)
     {
          //Print
          cout<<"The longest position starts
          at:"<<longestPosition<<endl;
          for(i=longestPosition;i<(longestPosition+longest);i++)
               cout<<"The "<<i<<"th element is "<<list[i]<<endl;
     }

        return;
}
4. You have a class that many libraries depend on. Now you need to modify the class for
   one application. Which of the following changes require recompiling all libraries before
   it is safe to build the application?

       a. add a constructor
       b. add a data member
       c. change destructor into virtual
       d. add an argument with default value to an existing member function

        a -The addition of a constructor will change the layout of the base class as well as the
classes derived from the base class. Also, because of the addition the compiler may need to choose
the user defined constructor instead of the default constructor created by the compiler. Possible
implicit conversion during construction of a new object will also occur due to the addition of new
constructer. All in all, it affects many aspect of how this class, the classes based on this class, and
the implementations involve the objects created from this class. Therefore the other files/classes
based on this file have to be recompiled.
        b – The addition of a data member will also affect the structure of this class and the classes
derived from this class. The memory occupation maybe changed due to one more data member.
Thus this activity will also cause the dependent files to be recompiled.
       c –Though which version of the virtual function to call will be decide in runtime, the virtual
destructor may create a vtbl and add one vptr to the class object. The addition of the virtual function
also needs recompilation of the class and dependent files.
       d – After addition of an argument with default value to a existing member function, the
compiler cannot decide if this is used or not in the dependent implementations. It’s kind of
changing the implementations of all the files those use this member function. As a result, the
compiler will also recompile the file to make sure they are implemented right.

      To avoid compilation dependency between files, one needs to use declaration dependency
when possible, instead of implementation dependency.

5. Implement the following car hierarchy along with the accessor functions and a
   CarRental class which contains the container to store them.
   A car rental company wants to keep track of its cars. Each vehicle has a license plate and a brand. (eg.
   BWM). Currently the company has SUV-s and Sedans. SUV-s have an optional third row seat, sedan’s
   have an optional sport package. Each car can be queried to inquire the number of passengers it can
   carry.

   #include<string>

   //The declaration of the base abstract class Car

   class Car
   {
     int id;
     string plate;
     string brand;
     int type;
     int capacity;
     //Prevent initial
   public:
     Car();
     Car(const int id, const string& plate, const string& brand,
   const int type, const int capacity=5):id(id), plate(plate),
   brand(brand), type(type), capacity(capacity){};
     Car(const Car& c);
     virtual ~Car()=0;

       const string getPlate(){return plate;};
       const string getBrand(){return brand;};
       const int getCapacity(){return Capacity;};

       void setPlate(const string& p){plate=p;};
       void setBrand(const string& b){brand=b;};
       void setCapacity(const int c){Capacity=c;};
   }
//The suv class. A bool member denotes if the vehicle has a
third row seat is added.
class suv:public Car
{
  bool thirdRowSeat;
public:
  suv();
  //The constructor of suv, the type is initialized to 1,
representing SUV.
  suv(const int id, const string& plate, const string& brand,
const int capacity=5, const bool thirdRowSeat=false):id(id),
plate(plate), brand(brand), type(1),capacity(capacity),
thirdRowSeat(thirdRowSeat){};
  suv(const suv& s);
  ~suv(){};
  const bool isThirdRowSeat(){return thirdRowSeat;};
  void setIsThirdRowSeat(const bool t){thirdRowSeat=t;};
}

//The class sedan. The type is initialized to 2
class sedan:public Car
{
  bool sportPackage;

public:
  sedan();
  sedan(const string& plate, const string& brand, const int
capacity=5, const bool sportPackage=false): id(id),
plate(plate), brand(brand), type(2),capacity(capacity),
sportPackage(sportPackage){};
  sedan(const sedan& s);
  ~sedan(){};
  const bool isSportPackage(){return sportPackage;};
  void setIsSportPackage(const bool s){sportPackage=t;};
}

//The container, the total number is implemented as a static int.
class CarRental
{
  static int total=100;
  Car* vehicle[total];
public:
  CarRental(){};
  ~CarRental(){};
  void addVehicle(const Car&);
  void RemoveVehicle(const int id);
  //more manipulation functions can be added here
    int getType(){return vehicle->type;}
    int getPassangers(){return vehicle->capacity;}

    //more access functions can be added here


}

				
DOCUMENT INFO
Shared By:
Categories:
Stats:
views:131
posted:3/20/2010
language:English
pages:6