從C到C++要注意的33件事(3)
阿新 • • 發佈:2018-12-24
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 vectora (4, 5) b (1, 2, 3) *r = b{ 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; }
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)double surface ()
{
y = n;
}
{
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++需要注意的一些點,沒什麼複雜的。其實翻譯這個系列文章的目的也是自己現在正處於這個挑戰中,也希望通過這個積累和構造自己的知識體系吧。同時也能和各位同學共勉。
如果同學們在看文章的過程中發現錯誤和有任何問題,意見,歡迎發表評論。我個人很願意和大家一起討論,進步。