十五到十九章

283 阅读3分钟

第十五章

15.23(回文)

#include <iostream> 
#include <vector>
using namespace std;

template < typename X >
bool palindrome(const vector< X >& vec)
{
    typename vector< X >::const_reverse_iterator r = vec.rbegin();
    typename vector< X >::const_iterator i = vec.begin();
    while (r != vec.rend() && i != vec.end())
    {
        if (*r != *i)
            return false;
        ++r;
        ++i;
    }
    return true;
}

template < typename Y >
void printVector(const vector< Y >& vec)
{
    typename vector< Y >::const_iterator i;
    for (i = vec.begin(); i != vec.end(); ++i)
        cout << *i << ' ';
}

int main()
{
    vector< int > iv;
    vector< char > ic;
    int x = 0;
    for (int i = 75; i >= 65; i--)
    {
        iv.push_back(i);
        ic.push_back(static_cast<char> (i + x));
        if (i <= 70)
            x += 2;
    }
    printVector(iv);
    cout << (palindrome(iv) ? " is " : " is not ") << "a palindrome\n";
    printVector(ic);
    cout << (palindrome(ic) ? " is " : " is not ") << "a palindrome\n";
}

15.24(使用bitset的爱拉托逊斯筛选法)

#include <iostream>
#include <iomanip>
#include <cmath>
#include <bitset>
using namespace std;

int main()
{
    const int SIZE = 1024;
    int i;
    int value;
    int counter;
    bitset< SIZE > sieve;
    sieve.flip();
    sieve.reset(0);
    sieve.reset(1);
    int finalBit = sqrt(static_cast<double>(sieve.size())) + 1;
    for (i = 2; i < finalBit; i++)
    {
        if (sieve.test(i))
        {
            for (int j = 2 * i; j < SIZE; j += i)
                sieve.reset(j);
        }
    }
    cout << "The prime numbers in the range 2 to 1023 are:\n";
    for (i = 2, counter = 1; i < SIZE; i++)
    {
        if (sieve.test(i))
        {
            cout << setw(5) << i;
            if (counter++ % 12 == 0)
                cout << '\n';
        }
    }
    cout << endl;
    cout << "\nEnter a value from 1 to 1023 (-1 to end): ";
    cin >> value;
    while (value != -1)
    {
        if (sieve[value])
            cout << value << " is a prime number\n";
        else
        {
            cout << value << " is not a prime number\n"
                << "prime factor(s): ";
            bool print = true;
            for (int f = 2; f < SIZE; )
            {
                if (sieve.test(f) && value % f == 0)
                {
                    if (print)
                        cout << f << ' ';
                    value /= f;
                    if (value <= 1)
                        break;
                    print = false;
                }
                else
                {
                    ++f;
                    print = true;
                }
            }ut << '\n';
        }
        cout << "\nEnter a value from 2 to 1023 (-1 to end): ";
        cin >> value;
    }
}

15.26(质因子)

#include <iostream> 
#include <iomanip> 
#include <cmath>
#include <bitset>
using namespace std;

int main()
{
    const int SIZE = 1024;
    int i;
    int value;
    int counter;
    bitset< SIZE > sieve;
    sieve.flip();
    sieve.reset(0);
    sieve.reset(1);
    int finalBit = sqrt(static_cast<double>(sieve.size())) + 1;
    for (i = 2; i < finalBit; i++)
    {
        if (sieve.test(i))
        {
            for (int j = 2 * i; j < SIZE; j += i)
                sieve.reset(j);
        }
    }
    cout << "The prime numbers in the range 2 to 1023 are:\n";
    for (i = 2, counter = 1; i < SIZE; i++)
    {
        if (sieve.test(i))
        {
            cout << setw(5) << i;

            if (counter++ % 12 == 0)
                cout << '\n';
        }
    }
    cout << endl;
    cout << "\nEnter a value from 1 to 1023 (-1 to end): ";
    cin >> value;
    while (value != -1)
    {
        if (sieve[value])
            cout << value << " is a prime number\n";
        else
        {
            cout << value << " is not a prime number\n"
                << "The unique prime factorization of " << value << " is: ";
            for (int f = 2; f < SIZE; )
            {
                if (sieve.test(f) && value % f == 0)
                {
                    cout << f;
                    value /= f;
                    if (value <= 1)
                        break;
                    cout << " * ";
                }
                else
                    ++f;
            }
            cout << '\n';
        }
        cout << "\nEnter a value from 2 to 1023 (-1 to end): ";
        cin >> value;
    }
}

第十六章

第十七章

17.21(从一个catch处理器抛出异常)

//TestException.h
#include <string>
#include <stdexcept>
using namespace std;

class TestException : public runtime_error 
{
public:
   TestException( const string& message ) 
      : runtime_error( message ) {}
};
//main.cpp
#include <iostream> 
#include "TestException.h"
using namespace std;

int main()
{
   try 
   {
      throw TestException( "This is a test" );
   } // end try
   catch ( TestException &t ) 
   {
      cerr << t.what() << endl;
      throw TestException( "This is another test" );
   }
}

17.22(捕获派生类的异常)

//DerivedException1.h
#include <string>
#include <stdexcept>
using namespace std;

class DerivedException1 : public runtime_error
{
public:
    DerivedException1(const string& message)
        : runtime_error(message) {}
};
//DerivedException2.h
#include <string>
#include <stdexcept>
using namespace std;

class DerivedException2 : public runtime_error
{
public:
    DerivedException2(const string& message)
        : runtime_error(message) {}
};
//main.cpp
#include <iostream> 
#include "DerivedException1.h"
#include "DerivedException2.h"
using namespace std;

int main()
{
   try
   {
      throw ( DerivedException1( "DerivedException1" ) );
   }
   catch ( runtime_error &exception )
   {
      cerr << exception.what() << endl;
   }
   try
   {
      throw ( DerivedException2( "DerivedException2" ) );
   }
   catch ( runtime_error &exception ) // exceptions of runtime_error
   {
      cerr << exception.what() << endl;
   }
}

17.23(抛出条件表达式的结果)

#include <iostream>
using namespace std;

int main()
{
   try
   {
      int a = 7;
      double b = 9.9;
      throw a < b ? a : b;
   }
   catch ( int x )
   {
      cerr << "The int value " << x << " was thrown\n";
   }
   catch ( double y )
   {
      cerr << "The double value " << y << " was thrown\n";
   }
}

17.24(局部变量的析构函数)

//TestObject.h
class TestObject 
{
public:
   TestObject( int );
   ~TestObject();
private:
   int value; 
};
//TestObject.cpp
//#include <iostream>
#include "TestObject.h"
using namespace std;

TestObject::TestObject(int val)
	: value(val)
{
	cout << "TestObject " << value << " constructor\n";
}

TestObject::~TestObject() 
{ 
   cout << "TestObject " << value << " destructor\n"; 
}
//main.cpp
#include <iostream>
#include <stdexcept>
#include "TestObject.h"
using namespace std;

int main()
{
    try
    {
        TestObject a(1);
        TestObject b(2);
        TestObject c(3);
        cout << '\n';
        throw runtime_error("This is a test exception");
    }
    catch (runtime_error& exception)
    {
        cerr << exception.what() << "\n";
    }
}

17.24(成员对象的析构函数)

//Item.h
class Item
{
public:
	Item(int);
	~Item();
private:
	int value;
}; 
//Item.cpp
#include <iostream>
#include <stdexcept>
#include "Item.h"
using namespace std;

Item::Item(int val) : value(val)
{
    cout << "Item " << value << " constructor called\n";
    if (value == 3)
        throw runtime_error("An exception was thrown");
}

Item::~Item()
{
    cout << "Item " << value << " destructor called\n";
}
//ItemGroup.h
#include "Item.h"

class ItemGroup
{
public:
	ItemGroup();
	~ItemGroup();
private:
	Item item1;
	Item item2;
	Item item3;
	Item item4;
	Item item5;
};
//ItemGroup.cpp
#include <iostream>
#include "ItemGroup.h"
using namespace std;

ItemGroup::ItemGroup()
	: item1(1), item2(2), item3(3), item4(4), item5(5)
{
	cout << "ItemGroup constructor called\n";
}

ItemGroup::~ItemGroup()
{
	cout << "ItemGroup destructor called\n";
}
//main.cpp
#include <iostream>
#include <stdexcept>
#include "ItemGroup.h"
using namespace std;

int main()
{
    cout << "Constructing an object of class ItemGroup\n";
    try
    {
        ItemGroup itemGroup;
    }
    catch (runtime_error& exception)
    {
        cout << exception.what() << '\n';
    }
}

17.26(捕获所有异常)

//TestException1.h
#include <string>
#include <stdexcept>
using namespace std;

class TestException1 : public runtime_error
{
public:
    TestException1()
        : runtime_error("TestException1") {}
};
//TestException2.h
#include <string>
#include <stdexcept>
using namespace std;

class TestException2 : public runtime_error
{
public:
    TestException2()
        : runtime_error("TestException2") {}
};
//main.cpp
#include <iostream>
#include <ctime>
#include <cstdlib>
#include "TestException1.h"
#include "TestException2.h"
using namespace std;

void generateException();

int main()
{
    srand(time(0));
    for (int i = 0; i < 5; i++)
    {
        try
        {
            generateException();
        }
        catch (...)
        {
            cerr << "The \"catch all\" exception handler was invoked\n";
        }
    }
}

void generateException()
{
    int type = 1 + rand() % 3;
    TestException1 exception1;
    TestException2 exception2;
    switch (type)
    {
    case 1:
        cout << "\nThrowing exception of type int...\n";
        throw(10);
    case 2:
        cout << "\nThrowing exception of type TestException1...\n";
        throw(exception1);
    case 3:
        cout << "\nThrowing exception of type TestException2...\n";
        throw(exception2);
    }
}

17.27(异常处理器的顺序)

//TestException.h
#include <iostream> 
#include "TestException.h"
using namespace std;

int main()
{
    try
    {
        throw TestException("This is a TestException");
    }
    catch (runtime_error& exception)
    {
        cout << "runtime_error was caught\n" << exception.what() << endl;
    }
    catch (TestException& exception) // catch TestException
    {
        cout << "TestException was caught\n" << exception.what() << endl;
    }
}
//TestException.h
#include <iostream>
#include "TestException.h"
using namespace std;

int main()
{
    try
    {
        throw TestException("This is a TestException");
    }
    catch (TestException& exception)
    {
        cout << "TestException was caught\n" << exception.what() << endl;
    }
    catch (runtime_error& exception)
    {
        cout << "runtime_error was caught\n" << exception.what() << endl;
    }
}
//main.cpp
#include <string>
#include <stdexcept>
using namespace std;

class TestException : public runtime_error
{
public:
    TestException(const string& message)
        : runtime_error(message) {}
};

17.28(构造函数抛出异常)

//IDObject.h
class IDObject
{
public:
	IDObject(int);
private:
	int idNumber;
};
//InvalidIDException.h
#include <string>
#include <stdexcept>
using namespace std;

class InvalidIDException : public runtime_error
{
public:
    InvalidIDException(const string& message)
        : runtime_error(message) {}
};
//IDObject.cpp
#include <iostream>
#include "IDObject.h"
#include "InvalidIDException.h"
using namespace std;

IDObject::IDObject(int id) : idNumber(id)
{
    cout << "Constructor for IDObject " << idNumber << '\n';
    if (idNumber < 0)
        throw InvalidIDException("ERROR: Negative ID number");
}
//main.cpp
#include <iostream> 
#include "IDObject.h"
#include "InvalidIDException.h"
using namespace std;

int main()
{
   try
   {
      IDObject valid( 10 );
      IDObject invalid( -1 );
   }
   catch ( InvalidIDException &exception )
   {
      cerr << exception.what() << '\n';
   }
}

17.29(重新抛出异常)

//TestException.h
#include <string>
#include <stdexcept>
using namespace std;

class TestException : public runtime_error
{
public:
    TestException(const string& message)
        : runtime_error(message) {}
};
//main.cpp
#include <iostream>
#include "TestException.h"
using namespace std;

void f() 
{ 
   throw TestException( "Test exception thrown" ); 
}

void g()
{
   try 
   {
      f();
   }
   catch ( ... )
   {
      cerr << "Exception caught in function g(). Rethrowing...\n";
      throw;
   }
}

int main()
{
   try 
   {
      g();
   }
   catch ( ... )
   {
      cerr << "Exception caught in function main()\n";
   }
}

17.30(未捕获到异常)

//TestException1.h
#include <string>
#include <stdexcept> 
using namespace std;

class TestException1 : public runtime_error
{
public:
    TestException1(const string& message)
        : runtime_error(message) {}
}; 
//TestException2.h
#include <string>
#include <stdexcept>
using namespace std;

class TestException2 : public runtime_error
{
public:
    TestException2(const string& message)
        : runtime_error(message) {}
};
//main.cpp
#include <iostream>
#include "TestException1.h"
#include "TestException2.h"
using namespace std;

void f()
{
    throw TestException1("TestException1");
}

void g()
{
    try
    {
        f();
    }
    catch (TestException2& t2)
    {
        cerr << "In g: Caught " << t2.what() << '\n';
    }
}

int main()
{
    try
    {
        g();
    }
    catch (TestException1& t1)
    {
        cerr << "In main: Caught " << t1.what() << '\n';
    }
}

17.31(堆栈展开)

//TestException.h
#include <string>
#include <stdexcept>
using namespace std;

class TestException : public runtime_error
{
public:
    TestException(const string& message)
        : runtime_error(message) {}
};
//main.cpp
#include <iostream>
#include "TestException.h"
using namespace std;

void f() 
{ 
   throw TestException( "TestException" ); 
}

void g() { f(); }

void h() { g(); }

int main()
{
   try 
   {
      h();
   }
   catch ( TestException &t ) // catch any exceptions that occurred in h
   {
      cerr << "In main: Caught " << t.what() << '\n';
   }
}

第十八章

18.3(模板中的运算符重载)

#include <iostream> 
using namespace std;

template < typename T >
bool isEqualTo(const T& arg1, const T& arg2)
{
    return arg1 == arg2;
}

class Complex
{
    friend ostream& operator<<(ostream&, Complex&);
public:
    Complex(int realPart, int iPart)
        : real(realPart),
        imaginary(iPart)
    {
    }
    bool operator==(const Complex& right) const
    {
        return real == right.real && imaginary == right.imaginary;
    }
private:
    int real;
    int imaginary;
};
 
ostream& operator<<(ostream& out, Complex& obj)
{
    if (obj.imaginary > 0)
        out << obj.real << " + " << obj.imaginary << "i";
    else if (obj.imaginary == 0)
        out << obj.real;
    else
        out << obj.real << " - " << -obj.imaginary << "i";
    return out;
}

int main()
{
    int a;
    int b;
    cout << "Enter two integer values: ";
    cin >> a >> b;
    cout << a << " and " << b << " are "
        << (isEqualTo(a, b) ? "equal" : "not equal") << '\n';
    char c;
    char d;
    cout << "\nEnter two character values: ";
    cin >> c >> d;
    cout << c << " and " << d << " are "
        << (isEqualTo(c, d) ? "equal" : "not equal") << '\n';
    double e;
    double f;
    cout << "\nEnter two double values: ";
    cin >> e >> f;
    cout << e << " and " << f << " are "
        << (isEqualTo(e, f) ? "equal" : "not equal") << '\n';
    Complex g(10, 5);
    Complex h(10, 5);
    cout << "\nThe class objects " << g << " and " << h << " are "
        << (isEqualTo(g, h) ? "equal" : "not equal") << '\n';
}

18.4(Array类模板)

//Array.h
#ifndef ARRAY1_H
#define ARRAY1_H

#include <iostream>
using namespace std;

template < typename elementType, int numberOfElements >
class Array
{
public:
    Array();
    ~Array();
    int getSize() const;
    bool operator==(const Array&) const;
    bool operator!=(const Array&) const;
    elementType& operator[](int);
    static int getArrayCount();
    void inputArray();
    void outputArray() const;
private:
    elementType elements[numberOfElements];
    static int arrayCount;
};

template < typename elementType, int numberOfElements >
int Array< elementType, numberOfElements >::arrayCount = 0;

template < typename elementType, int numberOfElements >
Array< elementType, numberOfElements >::Array()
{
    arrayCount++;
    for (int i = 0; i < numberOfElements; i++)
        elements[i] = elementType();
}

template < typename elementType, int numberOfElements >
Array< elementType, numberOfElements >::~Array()
{
    arrayCount--;
}

template < typename elementType, int numberOfElements >
int Array< elementType, numberOfElements >::getSize() const
{
    return numberOfElements;
}

template < class elementType, int numberOfElements >
bool Array< elementType, numberOfElements >::
operator==(const Array& right) const
{
    for (int i = 0; i < numberOfElements; i++)
    {
        if (elements[i] != right.elements[i])
            return false;
    }
    return true;
}

template < typename elementType, int numberOfElements >
bool Array< elementType, numberOfElements >::
operator!=(const Array& right) const
{
    for (int i = 0; i < numberOfElements; i++)
    {
        if (elements[i] != right.elements[i])
            return true;
    }
    return false;
}

template < typename elementType, int numberOfElements >
elementType &Array< elementType, numberOfElements >:: 
   operator[]( int subscript )
{
   assert( 0 <= subscript && subscript < numberOfElements ); 
   return elements[ subscript ];
}

template < typename elementType, int numberOfElements >
int Array< elementType, numberOfElements >::getArrayCount()
{
    return arrayCount;
}

template < typename elementType, int numberOfElements >
void Array< elementType, numberOfElements >::inputArray()
{
    for (int i = 0; i < numberOfElements; i++)
        cin >> elements[i];
}

template < typename elementType, int numberOfElements >
void Array< elementType, numberOfElements >::outputArray() const
{
    int i;
    for (i = 0; i < numberOfElements; i++)
    {
        cout << elements[i] << ' ';
        if ((i + 1) % 10 == 0)
            cout << '\n';
    }
    if (i % 10 != 0)
        cout << '\n';
}

#endif
//main.cpp
#include <iostream>
#include <string>
#include "Array.h"
using namespace std;

int main()
{
    Array< int, 5 > intArray;
    cout << "Enter " << intArray.getSize() << " integer values:\n";
    intArray.inputArray();
    cout << "\nThe values in intArray are:\n";
    intArray.outputArray();
    Array< string, 7 > stringArray;
    cout << "\nEnter " << stringArray.getSize()
        << " one-word string values:\n";
    stringArray.inputArray();
    cout << "\nThe values in the stringArray are:\n";
    stringArray.outputArray();
}

第十九章