Musings

A random collection

Archive for the ‘C++’ Category

C++: Adding INCLUDE directories Globally in MSVS 2010

  1. Open Project Property Sheets — View -> Other Windows -> Property Manager
  2. A Tab called “Property Manager” will open up next to the “Solution Explorer”
  3. Navigate to any project’s settings and open “Microsoft.Cpp.Win32.user” properties (right click on it)
  4. In the Property Pages dialog box, go to “VC++ Directories” and add Include Directories, Library Directories
  5. Ref: http://blogs.msdn.com/b/vsproject/archive/2009/07/07/vc-directories.aspx
Advertisements

Written by curious

March 10, 2011 at 1:42 pm

Posted in C++

C++: Explicit vs Implicit Constructors

Explicit constructors cannot take part in an implicit conversion.

class Array
{
public:
    Array(size_t count);            // implicit ctor
    explicit Array(size_t count);
};

Array array = 1; // implicit conversion, ok

void UseArray(const Array& arr);

UseArray(10);    // mistake, want to avoid
  1. Why do we need implicit conversion? Sometimes it is more natural allow implicit conversion
    class Number
    {
    public:
        Number(int n);
    };
    
    Number num = 1233; // natural to do this
    
  2. When do you not need explicit declaration on a constructor? When constructor has more than one parameters.
    class UserName
    {
    public:
        UserName(const string& first, const string& last);
    };
    
    UserName user("Arun", "Singh");
    

More examples

class BigBuffer
{
public:
 BigBuffer(int initialValue)
   { memset(buffer, initialValue, sizeof(buffer)); }
private:
 char buffer[65536];
};

extern void Foo(const BigBuffer& o);

void oops()
{
 Foo(3);
}

Written by curious

January 18, 2011 at 3:41 pm

Posted in C++

C++: Abstract Classes

Abstract Classes

  1. A class which does not fully represent an object. It only provides a partial description of its objects. The common description. It is expected that it’s subclasses will add to its structure and behavior.
  2. Example: Mammal does not fully represent any particular animal, but a particular animal may belong to the class of all Mammals
  3. Abstract classes organize features common to several classes. Common features that are features of the class’s interface.

Written by curious

December 25, 2010 at 10:57 am

Posted in C++

PROG: Comparison of data types

Type Bit Size Size
char at least 8 bits one byte
short at least 16 bits at least as big as a char
int at least 16 bits at least as big as a short
long at least 32 bits at least as big as int
  1. signed integer types
    signed char        // 8-bits
    signed short int     // 16-bits
    signed int             // 16 or 32 bits
    signed long int      // 32 bits
    signed long long int // 64 bits
    
  2. unsigned integer types
    unsigned char
    unsigned short int
    unsigned int
    unsigned long int
    unsigned long long int
    
  3. floating point types
    float
    double
    long double
    
  4. In addition to signed, unsigned integer types above, the following may also be used as integral values
    bool
    char
    wchar_t
    

Boost types

#include <boost/cstdint.hpp>

boost::int8_t   // signed char
boost::int16_t  // short
boost::int32_t  // long or int
boost::int64_t  // long long or long

boost::uint8_t   // unsigned char
boost::uint16_t  // unsigned short
boost::uint32_t  // unsigned long or unsigned int
boost::uint64_t  // unsigned long long or unsigned long

Note:

  1. char == signed char / unsigned char
  2. short == short int
  3. long == long int
  4. unsigned == unsigned int
  5. signed == signed int

Written by curious

November 10, 2010 at 10:38 am

Posted in C++

PROG: C++ Numeric Limits Options

In C++ there are multiple ways we can specify bounds values (MAX, MIN) for numeric types.

  1. Old C way (#include “limits.h”)
    Name
    CHAR_BIT
    SCHAR_MIN,MAX
    UCHAR_MAX
    CHAR_MIN,MAX
    SHRT_MIN,MAX
    USHRT_MAX
    INT_MIN,MAX
    UINT_MAX
    LONG_MIN,MAX
    ULONG_MAX
  2. STL way
    #include <limits>
    std::numeric_limits<int>::min()
    std::numeric_limits<int>::max()
    std::numeric_limits<int>::is_signed()
    std::numeric_limits<int>::digits() // number of bits
    std::numeric_limits<int>::has_infinity()
    std::numeric_limits<int>::infinity()
    
  3. Boost way
    #include <boost/numeric/conversion/bounds.hpp>
    #include <boost/limits.hpp>
    
    boost::numeric::bounds<int>::highest()
    boost::numeric::bounds<int>::lowest()  // min finite value numeric_limits<T>::min() or -numeric_limits<T>::max()
    boost::numeric::bounds<int>::smallest() // smallest denormalized value for floats, 0 for integral types
    

A safe numeric conversion/cast in Boost

Use it for numeric type to numeric type conversions

Will throw exceptions when it is unsafe to convert

  1. Conversions from an integral type with a wider range than the target integral type
  2. Conversions from unsigned to signed (and vice versa) integral types
  3. Conversions from floating point types to integral types
#include <boost/numeric/conversion/cast.hpp> 

doubled = boost::numeric_cast<double>(intval);

// exceptions
bad_numeric_cast
negative_overflow
positive_overflow

Lexical Cast in Boost

For conversion from non-numeric types

#include <boost/lexical_cast.hpp>

// may throw bad_lexical_cast exception
boost::lexical_cast<short>(stringval);
boost::lexical_cast<std::string>(intval);

Written by curious

November 10, 2010 at 9:54 am

Posted in C++

C++: Standard Library

STL provides:

  1. Containers:
    • vector, list, deque
    • stack, queue, priority_queue
    • map, set, bitset, multimap, multiset
  2. Iterators – copied (iter1 = iter2, , copy-constructed (Iterator iter1(iter2)), incremented (iter++, ++iter, *iter++)
    • input iterator – equality/inequality comparison (iter == end(), iter != end()), dereference as rvalue (i = *iter, iter->ival) – istream_iterator, istream_buf_iterator
    • output iterator – dereference as lvalue (*iter = x) – ostream_iterator, ostreambuf_iterator
    • forward iterator – default constructor (ForwardIterator iter, ForwardIterator())
    • bidirectional iterator – decrement (iter--, --iter, *iter--)
    • random access iterator – ptr arithmetic (iter + 10, iter-10, n = iter2-iter1), inequality comparison (iter1 < iter2, iter1 > iter2), compound assignment (+=, -=), offset dereference (iter[n])
    • Inserter iteratorsback_insert_iterator, front_insert_iterator, insert_iterator
    • Inserter iterator constructorsback_inserter, front_inserter, inserter
    • reverse_iterator
    • raw_storage_iterator
  3. Algorithms:
    • 12 non-modifying sequence operationsfor_each, find, find_if, find_end, find_first_of, adjacent_find, count, count_if, mismatch, equal, search, search_n
    • 27 modifying sequence operationscopy, copy_backward, swap, swap_ranges, iter_swap, transform, replace, replace_if, replace_copy, replace_copy_if, fill, fill_n, generate, generate_n, remove, remove_if, remove_copy, remove_copy_if, unique, unique_copy, reverse, reverse_copy, rotate, rotate_copy, random_shuffle, partition, stable_partition
    • 5 sortingsort, stable_sort, partial_sort, partial_sort_copy, nth_element
    • 4 binary search on sorted rangeslower_bound, upper_bound, equal_range, binary_search
    • 7 merge operationsmerge, inplace_merge, includes, set_union, set_intersection, set_difference, set_symmetric_difference
    • 4 heap operationspush_heap, pop_heap, make_heap, sort_heap
    • 7 min/max operationsmin, max, min_element, max_element, lexicographical_compare, next_permutation, prev_permutation
    • 4 numericaccumulate, adjacent_difference, inner_product, partial_sum
    • raw memoryuninitialized_copy, uninitialized_fill, uninitialized_fill_n
  4. Function Objects:
    • base classesunary_function, binary_function
    • arithmeticplus, minus, multiplies, divides, modulus, negate
    • comparisonequal_to, not_equal_to, greater, less, greater_equal, less_equal
    • logicallogical_and, logical_or, logical_not
    • negatorsnot1, not2
    • 2 parameter bindersbind1st, bind2nd
    • 3 convertorsptr_fun, mem_fun, mem_fun_ref
    • 14 instrumental typesunary_negate, binary_negate, binder1st, binder2nd, pointer_to_unary_function, pointer_to_binary_function, mem_fun_t, mem_fun1_t, const_mem_fun_t, const_mem_fun1_t, mem_fun_ref_t, mem_fun1_ref_t, const_mem_fun_ref_t, const_mem_fun1_ref_t
  5. valarray
  6. exceptionslogical (logic_error, domain_error, invalid_argument, length_error, out_of_range), runtime (runtime_error, range_error, overflow_error, underflow_error)
  7. memory – auto_ptr, auto_ptr_ref
  8. string
  9. RTTItypeid, type_info
  10. I/O Streamistream, ostream, iostream, streambuf, filebuf, stringbuf, ifstream, ofstream, fstream, istringstream, ostringstream, stringstream, getline – cin, cout, cerr, clog
  11. Locale

Written by curious

July 15, 2010 at 9:00 am

Posted in STL

C++: How to implement an assignment operator for the following class?

class TFoo : public TSuperFoo
{
private:
    TBar* fBar1;
    TBar* fBar2;

public:
    TFoo& operator=(const TFoo& that);
};

Reference: Anatomy article, with follow up article after comments.
Issues:

  1. Do we really need an assignment operator? Yes, definitely. Otherwise compiler will define one for us.
  2. Can Copy Constructor be same as Assignment operator? No, assignment operator must be aware of existing state of the object. Copy ctor gets raw memory with no prior state to worry about.
  3. Function definition: parameter must be const reference to TFoo, return must be reference to “*this” (to preserve semantics “a=b=c=d”), should not be virtual (for virtual function overridden in derived class must take exactly the same parameters -Err!!! Isn’t this relaxed a bit in newer C++. Ponder on it).
  4. Ownership and aliasing of pointers – 2 pointers pointing to the same object (this->fBar1, that.fBar1), who is responsible for deleting it?
  5. Instead of trying to do a memcpy(), better to just use copy constructor (fBar1 = new TBar(*that.fBar1))
  6. Remember to free memory already pointed by fBar1,fBar2 before you assign a new object to them
  7. Guard against accidentally assigning yourself (if (this != &that))
  8. Do not forget the ancestors, TSuperFoo. Call (TSuperFoo::operator=(that))
  9. Exception Safety: Remember to clean up in case there is an exception. Also in case of an exception leave the object unchanged, in a consistent state.
  10. Consider delegating work to auto_ptr
  11. Leverage auto_ptr completely, it can free up the memory for old pointer when you reset it with a new pointer
  12. What if other classes derive from TBar and fBar1, fBar2 happen to point to instances of derived classes?
  13. What if there are classes deriving from TFoo?

Written by curious

July 9, 2010 at 11:10 am

Posted in C++