前言
目的以及与其他书籍的区别
- 这本书目的主要是强调那些常被漠视的C++的编程的方向和观点。
- 其他书籍描述的是c++语言的各个成分,本书是告诉你如何结合这些成分以便获得有效的程序。
- 其他书籍告诉你如何让程序通过编译,本书是告诉你如何回避编译器难以显露的问题
声明式和定义式
声明式是告诉编译器某个东西的名称和类型
extern int x;
std::size_t numDigits(int num); //
class Widget;
template<class T> class GraphNode;
定义式是提供编译器一些声明式的细节:
- 对对象或者变量而言,定义式是编译器为此对象(或变量)拨发内存的起点;
- 对function而言,定义式提供了代码的本体
- 对class或者template class 而言,定义式列出了他们的成员
int x;
Widget my_widget;
std::size_t numDigits(int num)
{
size_t ret = 1;
while(num/10 != 0)
{
++ ret ;
num = num/10;
}
return ret ;
}
class Widget{
public :
Widget() {}
~Widget() {}
}
初始化
初始化是给予对象初值的过程。对于用户自定义类型的对象而言,初始化由构造函数执行
-
Default 构造函数
default构造函数是一个可被调用而不带任何实参,即要么没有参数,要么所有的参数都带有缺省值
当用户声明任意一个带有参数的构造函数后,编译器不会生成default构造函数。
class A{ public: A(int a); ~A(); } A a1; // error , no matched constructor,no default constuctor A a2(3); // ok
带有缺省值构造函数
class B{ public : // B(int x = 0, bool b = false,int c); // error,缺省值参数应该写在后面 // B(int c ,int x = 0, bool b = false);// ok B(int a = 2, int b =3, bool c = true):a_(a),b_(b),c_(c){}//ok private: int a_; int b_; bool c_; }; B testB(2,false); // a_ = 2,b_ = 0, c_ = true;
隐式转换:当含有只有一个参赛的构造函数时,编译器支持隐式转换,当构造函数声明为 explicit类型时,禁止隐式转换
class C { public : C(int a, bool b =false) {} ~C(){} } class C2 { public : explicit C2(int a, bool b =false) {} ~C2(){} } C testC = 3; //ok C2 testC2 = 3; // error C2 testC2= C2(3); //ok
-
copy构造函数 与 赋值运算符
copy构造函数被用来以同类对象来初始化自我对象
赋值运算符被用来从另一个对象中copy其值到自我对象
class Widget{ public : Widget(){} ~Widget(){} Widget(const Widget &rhs){} Widget & operator=(const Widget &rhs){} } Widget w1; // 默认构造 Widget w2(w1);//copy 构造 w1 = w2;// 赋值运算符 Widget w3=w1;// !!!copy 构造
新对象被定义时,一定会有个构造函数被调用,如上例中w3,并未调用赋值运算符,而是调用的copy构造。当没有新对象被定义时,调用的既是赋值运算符。
默认copy 构造采用值传递。