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>Most little: 6
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: 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 |