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

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

25 類的變數也可以是常量,就像靜態變數一樣

using namespace std;
#include <iostream>

class vector
{
public:

   double x;
   double y;
   const static double pi = 3.1415927;

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

   double cylinder_volume ()
   {
      return x * x / 4 * pi * y;
   }
};

int main()
{
   cout << "The value of pi: " << vector::pi << endl << endl;

   vector k (3, 4);

   cout << "Result: " << k.cylinder_volume() << endl;

   return 0;
}
Output
The value of pi: 3.14159

Result: 28.2743

26 一個類可以從其他的類派生過來,這個新的類可以繼承原有類的所有成員和方法,並且可以增加新的成員和方法

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

class vector
{
public:

   double x;
   double y;

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

   double module()
   {
      return sqrt (x*x + y*y);
   }

   double surface()
   {
       return x * y;
   }
};

class trivector: public vector    // trivector is derived from vector
{ public: double z; // added to x and y from vector trivector (double m=0, double n=0, double p=0): vector (m, n) { z = p; // Vector constructor will } // be called before trivector
// constructor, with parameters

// m and n. trivector (vector a) // What to do if a vector is { // cast to a trivector x = a.x; y = a.y; z = 0; } double module () // define module() for trivector { return sqrt (x*x + y*y + z*z); } double volume () { return this->surface() * z; // or x * y * z } }; int main () { vector a (4, 5); trivector b (1, 2, 3); cout << "a (4, 5) b (1, 2, 3) *r = b" << endl << endl; cout << "Surface of a: " << a.surface() << endl; cout << "Volume of b: " << b.volume() << endl; cout << "Surface of base of b: " << b.surface() << endl; cout << "Module of a: " << a.module() << endl; cout << "Module of b: " << b.module() << endl; cout << "Module of base of b: " << b.vector::module() << endl; trivector k; k = a; // thanks to trivector(vector) definition
// copy of x and y, k.z = 0 vector j; j = b; // copy of x and y. b.z leaved out vector *r; r = &b; cout << "Surface of r: " << r->surface() << endl; cout << "Module of r: " << r->module() << endl; return 0; }
a (4, 5)    b (1, 2, 3)    *r = b

Surface of a: 20
Volume of b: 6
Surface of base of b: 2
Module of a: 6.40312
Module of b: 3.74166
Module of base of b: 2.23607
Surface of r: 2

Module of r: 2.23607

27  在上面的程式裡面,r->module 計算vector的模型,這樣做為什麼可以是因為r被宣告為vector類的指標。但是我們要記住,如果你想程式檢查這種物件的指標或者使用相關的方法,那麼我們必須把類裡面的方法宣告為虛擬函式。

(如果繼承的基類裡面有至少一個方法被宣告為虛擬函式的話,那麼每一個例項都會被加上事實上的4個Byte的指標,當然,64位有可能是8個Byte)。

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

class vector
{
public:

   double x;
   double y;

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

   virtual double module()
   {
      return sqrt (x*x + y*y);
   }
};

class trivector: public vector
{
public:
   double z;

   trivector (double m = 0, double n = 0, double p = 0)
   {
      x = m;                  // Just for the game,
      y = n;                  // here I do not call the vector
      z = p;                  // constructor and I make the
   }                          // trivector constructor do the
// whole job. Same result. double module () { return sqrt (x*x + y*y + z*z); } }; void test (vector &k) { cout << "Test result: " << k.module() << endl; } int main () { vector a (4, 5); trivector b (1, 2, 3); cout << "a (4, 5) b (1, 2, 3)" << endl << endl; vector *r; r = &a; cout << "module of vector a: " << r->module() << endl; r = &b; cout << "module of trivector b: " << r->module() << endl; test (a); test (b); vector &s = b; cout << "module of trivector b: " << s.module() << endl; return 0; }
Output
a (4, 5)    b (1, 2, 3)

module of vector a: 6.40312
module of trivector b: 3.74166
Test result:          6.40312
Test result:          3.74166
module of trivector b: 3.74166

28 你可能想知道一個類是否可以同時繼承多個類, 那麼答案是對的

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

class vector
{
public:

   double x;
   double y;

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

   double surface()
   {
      return fabs (x * y);
   }
};

class number
{
public:

   double z;

   number (double a)
   {
      z = a;
   }

   int is_negative ()
   {
      if (z < 0) return 1;
      else       return 0;
   }
};

class trivector: public vector, public number
{
public:

   trivector(double a=0, double b=0, double c=0): vector(a,b), number(c)
   {
   }           // The trivector constructor calls the vector
// constructor, then the number constructor,
// and in this example does nothing more.
double volume() { return fabs (x * y * z); } }; int main () { trivector a(2, 3, -4); cout << a.volume() << endl; cout << a.surface() << endl; cout << a.is_negative() << endl; return 0; }
Output
24
6
1

29 類的繼承可以讓你依據基類設計更負責的類,而另外一個用處則是可以讓程式設計師寫出一些通用的函式。

當我們寫了一個沒有任何變數的基類的時候,在你的程式裡面是沒有辦法使用這個類的。也就是說當你想繼承這個類的時候,就一定要讓成員函式正確的在類裡被定義,這樣才能合理的繼承基類

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

class octopus
{
public:

virtual double module() = 0; // = 0 implies function is not
// defined. This makes instances
// of this class cannot be declared.
}; double biggest_module (octopus &a, octopus &b, octopus &c) { double r = a.module(); if (b.module() > r) r = b.module(); if (c.module() > r) r = c.module(); return r; } class vector: public octopus { public: double x; double y; vector (double a = 0, double b = 0) { x = a; y = b; } double module() { return sqrt (x * x + y * y); } }; class number: public octopus { public: double n; number (double a = 0) { n = a; } double module() { if (n >= 0) return n; else return -n; } }; int main () { vector k (1,2), m (6,7), n (100, 0); number p (5), q (-3), r (-150); cout << biggest_module (k, m, n) << endl; cout << biggest_module (p, q, r) << endl; cout << biggest_module (p, q, n) << endl; return 0; }
Output
100
150
100

30 public:這些變數或者函式能夠被外部程式方位

   protect:僅能被類本身或者繼承類訪問

   private:只能被自己類的方法所訪問。

using namespace std;
#include <iostream>

class vector
{
protected:

   double x;
   double y;

public:

   void set_x (int n)
{
x = n;
}
   void set_y (int n)
{
y = n;
}
double surface ()
{
double s;
s = x * y;
if (s < 0) s = -s;
return s;
}
};

int main ()
{
vector a;

a.set_x (3);
a.set_y (4);

cout << "The surface of a: " << a.surface() << endl;

return 0;
}
Output
The surface of a: 12
31 讓我們看看C++是怎麼讀寫檔案的
這是寫一個檔案的 程式
using namespace std;
#include <iostream>
#include <fstream>

int main ()
{
   fstream f;

   f.open("test.txt", ios::out);

   f << "This is a text output to a file." << endl;

   double a = 345;

   f  << "A number: " << a << endl;

   f.close();

   return 0;
}

Content of file test.txt
This is a text output to a file. A number: 345
下面是怎麼讀檔案
using namespace std;
#include <iostream>
#include <fstream>

int main ()
{
   fstream f;
   char c;

   cout << "What's inside the test.txt file" << endl;
   cout << endl;

   f.open("test.txt", ios::in);

   while (! f.eof() )
   {
      f.get(c);                          // Or c = f.get()
      cout << c;
   }

   f.close();

   return 0;

32 有時候我們可以像檔案一樣操作字元陣列,這對我們在轉換和管理記憶體陣列的時候很有用
using namespace std;
#include <iostream>
#include <strstream>
#include <cstring>
#include <cmath>

int main ()
{
   char a[1024];
   ostrstream b(a, 1024);

   b.seekp(0);                           // Start from first char.
   b << "2 + 2 = " << 2 + 2 << ends;     // ( ends, not endl )
// ends is simply the
// null character '\0' cout << a << endl; double v = 2; strcpy (a, "A sinus: "); b.seekp(strlen (a)); b << "sin (" << v << ") = " << sin(v) << ends; cout << a << endl; return 0; }
Output
2 + 2 = 4
A sinus: sin (2) = 0.909297

33 C++可以格式化輸出用兩個不同的方式,要注意到,width()和setws()只對下一個要輸出的物件起作用。
using namespace std;
#include <iostream>
#include <iomanip>

int main ()
{
   int i;

   cout << "A list of numbers:" << endl;
   for (i = 1; i <= 1024; i *= 2)
   {
      cout.width (7);
      cout << i << endl;
   }

   cout << "A table of numbers:" << endl;
   for (i = 0; i <= 4; i++)
   {
      cout << setw(3) << i << setw(5) << i * i * i << endl;
   }

   return 0;
}
Output
A list of numbers:       1       2       4       8      16      32      64     128     256     512    1024 A table of numbers:   0    0   1    1   2    8   3   27   4   64
以上是一些基本的C++的知識,主要是針對一些C使用者轉換到C++需要注意的一些點,沒什麼複雜的。其實翻譯這個系列文章的目的也是自己現在正處於這個挑戰中,也希望通過這個積累和構造自己的知識體系吧。同時也能和各位同學共勉。
如果同學們在看文章的過程中發現錯誤和有任何問題,意見,歡迎發表評論。我個人很願意和大家一起討論,進步。