1. 程式人生 > >從C到C++要注意的33件事(1)

從C到C++要注意的33件事(1)

11.你可能知道一些C語言中的經典控制語句,但是C++增加了一些新的,像EXCEPTION
using namespace std;
#include <iostream>
#include <cmath>

int main ()
{
   int a, b;

   cout << "Type a number: ";
   cin >> a;
   cout << endl;

   try
   {
      if (a > 100) throw 100;
      if (a < 10)  throw 10;
      throw a / 3;
   }
   catch (int result)
   {
      cout << "Result is: " << result << endl;
      b = result + 1;
   }

   cout << "b contains: " << b << endl;

   cout << endl;

   // another example of exception use:

   char zero []     = "zero";
   char pair []     = "pair";
   char notprime [] = "not prime";
   char prime []    = "prime";

   try
   {
      if (a == 0) throw zero;
      if ((a / 2) * 2 == a) throw pair;
      for (int i = 3; i <= sqrt (a); i++)
      {
         if ((a / i) * i == a) throw notprime;
      }
      throw prime;
   }
   catch (char *conclusion)
   {
      cout << "The number you typed is "<< conclusion << endl;
   }

   cout << endl;

   return 0;
}
Output
Type a number: 5 Result is: 10 b contains: 11 The number you typed is prime
12 函式可以有預設引數
using namespace std;
#include <iostream>

double test (double a, double b = 7)
{
   return a - b;
}

int main ()
{
   cout << test (14, 5) << endl;    // Displays 14 - 5
   cout << test (14) << endl;       // Displays 14 - 7
return 0; }
Output
9
7

13 C++很重要的一點是函式過載, 編譯器可以通過引數個數,型別等來識別同樣命名的函式
using namespace std;
#include <iostream>

double test (double a, double b)
{
   return a + b;
}

int test (int a, int b)
{
   return a - b;
}

int main ()
{
   double   m = 7,  n = 4;
   int      k = 5,  p = 3;

   cout << test(m, n) << " , " << test(k, p) << endl;

   return 0;
}
Output
11 , 2

14 通過運算子過載可以定義一些新的引數型別
using namespace std;
#include <iostream>

struct vector
{
   double x;
   double y;
};

vector operator * (double a, vector b)
{
   vector r;

   r.x = a * b.x;
   r.y = a * b.y;

   return r;
}

int main ()
{
   vector k, m;              // No need to type "struct vector"

   k.x =  2;                 // To be able to write
   k.y = -1;                 // k = vector (2, -1)
                             // see chapter 19.

   m = 3.1415927 * k;        // Magic!

   cout << "(" << m.x << ", " << m.y << ")" << endl;

   return 0;
}
(6.28319, -3.14159)
15 在C中你可以能定義一樣的函式多次,分別為了不同的輸入引數,int, float, double,有可能還會忘記一些,C++可以幫助你解決這個問題,那就是通過模版類。
using namespace std;
#include <iostream>

template <class ttype>
ttype minimum (ttype a, ttype b)
{
ttype r;

r = a;
if (b < a) r = b;

return r;
}
int main () { int i1, i2, i3; i1 = 34; i2 = 6; i3 = minimum (i1, i2); cout << "Most little: " << i3 << endl; double d1, d2, d3; d1 = 7.9; d2 = 32.1; d3 = minimum (d1, d2); cout << "Most little: " << d3 << endl; cout << "Most little: " << minimum (d3, 3.5) << endl; return 0; }
Most little: 6
Most little: 7.9
Most little: 3.5

16 new和delete可以用來申請和釋放記憶體,他們比C中的malloc和free更整潔些,還可以用來釋放陣列型別存廢昂
using namespace std;
#include <iostream>
#include <cstring>

int main ()
{
   double *d;                         // d is a variable whose purpose
// is to contain the address of a
// zone where a double is located
d = new double; // new allocates a zone of memory
// large enough to contain a double
// and returns its address.
// That address is stored in d.
*d = 45.3; // The number 45.3 is stored
// inside the memory zone
// whose address is given by d.
cout << "Type a number: "; cin >> *d; *d = *d + 5; cout << "Result: " << *d << endl; delete d; // delete deallocates the
// zone of memory whose address
// is given by pointer d.
// Now we can no more use that zone. d = new double[15]; // allocates a zone for an array
// of 15 doubles. Note each 15
// double will be constructed.
// This is pointless here but it
// is vital when using a data type
// that needs its constructor be
// used for each instance.
d[0] = 4456; d[1] = d[0] + 567; cout << "Content of d[1]: " << d[1] << endl; delete [] d; // delete [] will deallocate the
// memory zone. Note each 15
// double will be destructed. // This is pointless here but it
// is vital when using a data type
// that needs its destructor be
// used for each instance (the ~
// method). Using delete without
// the [] would deallocate the
// memory zone without destructing
// each of the 15 instances. That
// would cause memory leakage. d = new double[n]; // new can be used to allocate an
// array of random size. for (int i = 0; i < n; i++) { d[i] = i; } delete [] d; char *s; s = new char[100]; strcpy (s, "Hello!"); cout << s << endl; delete [] s; return 0; }
Output
Type a number: 6 Result: 11 Content of d[1]: 5023 Hello!
17 標準C中,結構只能包括資料。但是在C++中,結構可以包括函式,這些函式能夠使用結構內部的資料。我們叫這種函式為方法
using namespace std;
#include <iostream>

struct vector
{
   double x;
   double y;

   double surface ()
{
double s;
s = x * y;
if (s < 0) s = -s;
return s;
} }; int main () { vector a; a.x = 3; a.y = 4; cout << "The surface of a: " << a.surface() << endl; return 0; }
Output
The surface of a: 1

18 建構函式和解構函式,他們分別在類的例項建立和刪除的時候呼叫。建構函式可以用來做初始化類等一些在類建立例項的時候需要的工作,而解構函式往往是釋放資源。
using namespace std;
#include <iostream>

class vector
{
public:

   double x;
   double y;

   vector ()                     // same name as class
   {
      x = 0;
      y = 0;
   }

   vector (double a, double b)
   {
      x = a;
      y = b;
   }

};

int main ()
{
   vector k;                     // vector () is called

   cout << "vector k: " << k.x << ", " << k.y << endl << endl;

   vector m (45, 2);             // vector (double, double) is called

   cout << "vector m: " << m.x << ", " << m.y << endl << endl;

   k = vector (23, 2);           // vector created, copied to k, then erased

   cout << "vector k: " << k.x << ", " << k.y << endl << endl;

   return 0;
}
Output
vector k: 0, 0

vector m: 45, 2

vector k: 23, 2

19 如果你像容器一樣例項化一個物件,那麼所有的問題都不存在。舉個例子,如果vector k 包括(4,7),那麼如果我們例項化m=k,,m也會有(4,7),
k.x和k.y會被複制給m.x,m.y.現在假設你有個person類,裡面有一個字串指標,如果你例項化這個person類通過p=r,那麼會有一些工作用來保證p被正確的從r上覆制過來。然而p.name指向和r.name一樣的物理字串,並且p.name指向的字元指標有可能會丟失成為記憶體洩露。
拷貝建構函式可以正確的讓你的物件複製拷貝在物件進行計算的時候,這是一個類的關鍵方法。
using namespace std;
#include <iostream>
#include <cstring>

class person
{
public:

   char *name;
   int age;

   person (char *n = "no name", int a = 0)
   {
      name = new char[100];
      strcpy (name, n);
      age = a;
   }

   person (const person &s)      // The COPY CONSTRUCTOR
   {
      name = new char[100];
      strcpy (name, s.name);
      age = s.age;
   }

   person& operator= (const person &s)  // overload of =
   {
      strcpy (name, s.name);
      age = s.age;
      return *this;
   }

   ~person ()
   {
      delete [] name;
   }
};

void modify_person (person& h)
{
   h.age += 7;
}

person compute_person (person h)
{
   h.age += 7;
   return h;
}


int main ()
{
   person p;
   cout << p.name << ", age " << p.age << endl << endl;
   // output: no name, age 0

   person k ("John", 56);
   cout << k.name << ", age " << k.age << endl << endl;
   // output: John, age 56

   p = k;
   cout << p.name << ", age " << p.age << endl << endl;
   // output: John, age 56

   p = person ("Bob", 10);
   cout << p.name << ", age " << p.age << endl << endl;
   // output: Bob, age 10

   // Neither the copy constructor nor the overload
// of = are needed for this operation that modifies
// p since just the reference towards p is passed to
// the function modify_person:
modify_person (p); cout << p.name << ", age " << p.age << endl << endl; // output: Bob, age 17 // The copy constructor is called to pass a complete
// copy of p to the function compute_person. The
// function uses that copy to make its computations
// then a copy of that modified copy is made to
// return the result. Finally the overload of = is
// called to paste that second copy inside k: k = compute_person (p); cout << p.name << ", age " << p.age << endl << endl; // output: Bob, age 17 cout << k.name << ", age " << k.age << endl << endl; // output: Bob, age 24 return 0; }
Output
no name, age 0

John, age 56

John, age 56

Bob, age 10

Bob, age 17

Bob, age 17

Bob, age 24