《C++程序设计语言》10_类

来源:互联网 发布:java编程思想 pdf 下载 编辑:程序博客网 时间:2024/06/11 07:05
1、成员有const和引用的类必须显示提供(默认)构造函数。2、赋值运算符的一般性策略:防止自赋值、删除那些老元素、初始化、复制那些新元素。通常非静态的成员都必须复制。Table::Table(const Table &t)//复制构造函数{p = new Name[sz = t.sz];for(int i = 0; i < sz; i++){p[i] = t.p[i];}}Table& Table::operator=(const Table &t)//赋值{if(this != &t)//防止自赋值{delete []p;//删除老元素p = new Name[sz = t.sz];//申请新资源for(int i = 0; i < sz; i++)//初始化{p[i] = t.p[i];}}return *this;}3、成员的构造函数将在容器本身的构造函数体执行之前首先被执行。这些构造函数按照成员在类中声明的顺序执行,而不是按这些成员在初始式表中出现的顺序。如果某个类对象中包含着一些类对象,当该对象被时,它自己的析构函数将首先被执行,而后将按照与声明相反的顺序执行各个成员的析构。4、构造时,初始式比赋值式往往更有效率上的优势。Person::Person(const string &n, const string &a) : name(n){address = a;}这里的 name 用 n 的一个副本进行初始化。而对 address 将先用一个空串初始化,而后又用 a 的副本赋值。5、成员常量class Curious{public:static const int c1 = 7;static int c2 = 11;//错误:非constconst int c3 = 12;//错误:非staticstatic const int c4 = f(14);//错误:在类里的初始表达式不是常量static const float c5 = 7.0;//错误:在类里初始化的不是整型};//example:static int f(int t){return t;}class Curious{public:static const int c1 = 7;//static const int c2 = f(1);//error C2057: expected constant expression//static const float c3 = 7.0;//error C2864: 'Curious::c3' : only static const integral data members can be initialized within a classstatic const int c2;static const float c3;};const int Curious::c2 = f(3);//ok,编译能通过const float Curious::c3 = 7.0;//ok,编译能通过6、局部静态存储对于局部静态对象,构造函数式在控制线程第一次通过该对象的定义时调用。//example:void f(int i){static Table tbl;if(i){static Table tbl2;}}int main(){f(0);//只构造 tbl,不构造 tbl2f(1);//不构造 tbl 了,构造 tbl2f(2);}7、非局部存储在所有函数之外定义的变量(即全局变量、名字空间的变量,以及各个类的static变量)在main() 被激活之前完成初始化,对于已经构造的所有这些变量,其析构函数将在退出main()之后调用。在一个编译单位里,对非局部变量的构造将按照它们的定义顺序进行。//example:class X{//...static Table memtbl;};Table tbl;Table X::memtbl;namespace Z{Table tbl2;}构造顺序:tbl -> X::memtbl -> Z::tbl2.注意:如在X里的memtbl声明一类的声明(与定义不同)并不影响构造顺序。对于不同编译单位里的非局部变量,其构造顺序就没有保证了,完全依赖于具体的实现。8、临时对象A、完整表达式:那种不是其他表达式的子表达式的表达式称为完整表达式。如下面的s1 + s2:void f(string &s1,string &s2, string &s3){const char *cs = (s1 + s2).c_str();cout << cs;if(strlen(cs = (s2 + s3).c_str() < 8 && cs[0] == 'a'){//在这里使用cs}}注意:为保存是 s1 + s2将会产生一个临时对象,在表达式结束时,这个临时对象将被删除。继续操作cs是危险的。B、返回索引到局部变量的引用也是错误的。int &f(){int local;...return &local;}9、对象的放置void *operator new(size_t, void *p);void *buf = reinterpret_cast<void*>(0xF00F);X* p2 = new(buf)X;//在“buf”构造X时调用:operator new(sizeof(X),buf)为operator new提供额外参数的new (buf) X的这种语法形式被称做放置语法。注意,每个new总以对象的大小作为其第一个参数,而被分配对象的大小是隐式提供的示例:class NewTest{public:NewTest(){nArray[0] = 10;nArray[1] = 9;nArray[2] = 8;nArray[3] = 7;nArray[4] = 6;}NewTest(int t){nArray[0] = 5;nArray[1] = 4;nArray[2] = 3;nArray[3] = 2;nArray[4] = 1;}private:int nArray[5];};int _tmain(int argc, _TCHAR* argv[]){NewTest *pNewTest = new NewTest(1);  NewTest *p = new   (pNewTest)   NewTest();//new后面以及 pNewTest后面的空白可有可无//p 以及 pNewTest 指向同一个地址,同时删除会出错//delete p;delete pNewTest;system("pause");return 0;}10、联合命名联合的定义方式同struct,其中的每个成员将具有同样的地址。联合可以有成员函数,但却不能有静态成员。一般来说,编译器无法知道被使用的是联合的哪个成员;也就是说,无法知道存储在联合中的对象的类型。因此,联合就不能包含带有构造函数或析构函数的成员,因为无法保护其中的对象以防止破坏,也不能保证在联合离开作用域时能调用正确的析构函数。


0 0
原创粉丝点击