|
12 2013 档案
摘要:虚函数是否可以内联? 一般来说,inline是编译时的行为,虚函数是在程序执行时的行为,因此编译器一般会拒绝对虚函数进行内联!
阅读全文
摘要:1.何为菱形继承?两个子类继承同一个父类,而又有子类又分别继承这两个子类,就如上图说示。#include#include#includeusing namespace std;class A {public: A(){printf("A create.\n");} int a; virtual void fun(){}};class B: public A{public: B(){printf("B create.\n");} int b; virtual void fun1(){}};class C: public A{public : int c;.
阅读全文
摘要:发帖水王:一堆数中有一个数字出现的次数多于1/2,问那个数? 比较简单的思路就是两个变量,一个记录当前的数字a,另一个记录当前数字出现的次数size,下一个数字与a相同的时候,size++,不同的时候:size>1,则size--;否则更新a,size=1; 加强版:一堆数中有3个数字出现的次数多于1/4,问是哪三个数? 思维迁移,用3个{a,size}量保存当前更新的数,下一个数字的时候,看这三个里面是否有这个数字存在,若是,则相应的size++;否则,找出sizez最小的那个量,size>1,则size--;否则更新a,size=1; #include#include#in..
阅读全文
摘要:之前没注意static这个关键词,被人问到的时候竟然不知道= =!果断补补 1.全局变量与静态全局变量,全局变量可以在声明的情况下,在项目的各个文件通用,静态全局变量就只能在当前定义的文件下使用。 1)全局变量是不显式用static修饰的全局变量,但全局变量默认是动态的,作用域是整个工程,在一个文件内定义的全局变量,在另一个文件中,通过extern 全局变量名的声明,就可以使用全局变量。 2)全局静态变量是显式用static修饰的全局变量,作用域是声明此变量所在的文件,其他的文件即使用extern声明也不能使用。//Example 2//File1 第一个代码文件的代码#includ...
阅读全文
摘要:拷贝构造函数大家都比较熟悉,通俗讲就是传入一个对象,拷贝一份副本。 不过看似简单的东西,实际不注意的话就会产生问题!#includeusing namespace std;class CExample {public: int a,b,c; char *str;public: //构造函数 CExample(int tb) { a = tb; b = tb+1; c = tb+2; str=(char *)malloc(sizeof(char)*10); strcpy(str,"1234...
阅读全文
摘要:在用到delete的时候,我们往往会针对类对象与类对象数组做不同删除,在这背后编译器是如何做的?#includeusing namespace std;class A{ int a;public: ~A(){ printf("delete A\n"); }};int main(){ A *pa = new A ; A *pas = new A[10] ; //delete []pas; //详细流程 //delete []pa; //会发生什么 //delete pas;...
阅读全文
摘要:三门问题,其中有一扇门后面有一辆车,两扇门后面是山羊,你随意选择了一扇门,这时,主持人打开了某一扇门是山羊,问你换不换你刚才选的门。 大部分人应该跟我的想法是一样的,换不换有区别么?区别大了!网上找了下资料,这个解释是比较通俗易懂的。 如果让3000个人来选,那么第一次选的时候,按照概率,会有1000个人左右选中,是吧? 对于每个观众,主持人展示了一扇没有奖的门之后,说:“虽然给你去掉了一个错误答案,但是你没有反悔的机会。”这就相当于,每个人都选择了不换。于是最终,一开始选中的那1000人得到了奖。也就是说,如果不换的话,获奖概率为1/3。 也可以反过来:主持人展示了一扇没有奖的门...
阅读全文
摘要:引入:这段时间一直在思考虚函数表的问题,同时也想知道虚函数表是在什么时候产生的本人是在VS2010的环境下,如有错误欢迎指出,谢谢。观察代码#include#includeclass A{public:A(); virtual~A(); void fun1(){ printf("123"); }};A::A(){ printf("new A\n");}A::~A(){ printf("Delete class A\n");}class B : public A{public:B(); ~B(); vo...
阅读全文
摘要:对于类中的成员变量的初始化要注意:考虑:#includeusing namespace std;class A{private: int n1; int n2; public: A():n2(0),n1(n2+2){} void Print(){ cout using namespace std;class A{private: int n1; int n2; public: //A():n2(0),n1(n2+2){} //n1:-858993458, n2: 0 //A():n1(n2+2),n2(0){}...
阅读全文
摘要:以前虽然考虑过这个问题,但是试了下以后就以为虚函数表在内存的代码区里,后来还被问到虚函数表在内存中的哪里,回答不同编译器对虚函数的处理是不一样的,今天仔细的测了测。 当然以下的测试是在win7的VS2010下。有错误欢迎批评指出,谢谢。 测试代码#include using namespace std;class Base1 {public: virtual void f() { cout << "Base1::f" << endl; } virtual void g() { cout << "Base1::g" &l
阅读全文
摘要:《c++ primer》中这样写的:引用在内部存放的是一个对象的地址,它是该对象的别名。对于不可寻址的值,如文字常量,以及不同类型的对象,编译器为了实现引用,必须生成一个临时对象,引用实际上是指向该对象,但用户不能访问它。#include#pragma pack(1)class data{public: double data_a; double &data_ra; data():data_ra(data_a){ //引用不能在构造函数体内初始化,要在构造函数名称右边初始化 data_a=1.0; }};int main(){ double...
阅读全文
摘要:问题的引出:一个类D继承自两个类B1,B2,而B1,B2都继承与基类B#includeusing namespace std; class B{ public: int ib; char cb; public: B():ib(0),cb('B') { printf("B found\n"); } virtual void f() { cout ib=111;由于二义性 这样会有问题 //printf("%d\n",d->ib); d->B1::ib=222; //pri...
阅读全文
摘要:引子:在算法运用迭代器的时候,很可能用到起相应型别(即迭代器所指之物的型别),但C++支持sizeof ,并无typeof。 可以利用function template的参数推导机制。1.函数参数的情况#includeusing namespace std;template void func_impl(I iter,T t){ T tmp;//这里解决了问题,T就是迭代器所指之物的类型 //…………}template void func(I iter){ func_impl(iter,*iter);}int main(){ int i; func(&i);}显...
阅读全文
摘要:引出:写个类A,声明类A指针指向NULL,调用类A的方法会有什么后果,编译通过吗,运行会通过吗?(在VS2008与VC++的情况下) 有错误欢迎批评指正!#include#includeusing namespace std;class base{ int a;public: void fun(){ printf("base fun\n"); }};int main(){ base *b=NULL; b->fun();}看到这个的时候,一定以为运行会报错吧。但是奇迹般的,编译器输出了:base fun#include#includeusing nam...
阅读全文
摘要:我们往往在类中的函数体,重载操作中看到const T & 的影子,以前还是比较纳闷。 对于非内部数据类型的参数而言,象void Func(A a) 这样声明的函数注定效率比较底。因为函数体内将产生 A 类型的临时对象用于复制参数 a,而临时对象的构造、复制、析构过程都将消耗时间。 为了提高效率,可以将函数声明改为void Func(A &a),因为“引用传递”仅借用一下参数的别名而已,不需要产生临时对象。但是函数 void Func(A &a) 存在一个缺点:“引用传递”有可能改变参数 a,这是我们不期望的。解决这个问题很容易,加 const修饰即可,因此函数最终成为
阅读全文
摘要:#include#include#include#include#includeusing namespace std;class Base{private: int x; char *p;public: Base(void){ x=0; p=(char *)malloc(sizeof(10)); strcpy(p,"123456"); } void Set_x(int tx){ x=tx; } //函数名后面加const表示这个对象指针this所指之物是无法改变的 int Get_x()c...
阅读全文
摘要:在编写派生类的赋值函数时,注意不要忘记对基类的数据成员重新赋值。#include#include#include#include#includeusing namespace std;class Base{private: int x,y;public: Base& operator =(const Base &other){ x=other.x; y=other.y; printf("Base operator\n"); return *this; } Base(){ x=0;y=0; ...
阅读全文
摘要:#include#include#include#include#includeusing namespace std;class mystring{public: mystring(const char *str=NULL); mystring(const mystring &other); ~mystring(void); mystring &operator=(const mystring &other); mystring &operator+=(const mystring &other); char *getString();private:
阅读全文
摘要:#includeusing namespace std;class Obj{public : Obj(){coutInit(); //~~~~~ a->Destroy(); free(a);}void new_test(){ Obj * a=new Obj; delete a;}int main(){ malloc_test(); new_test();}除了前者是函数,后者是标识符的区别外前者是在C语言中诞生的,用于内存分配但是不会执行构造函数与析构函数。(这里没有继承,要是有继承关系,用free就难以处理从派生类到基类的析构了,内存泄露在所...
阅读全文
摘要:前段时间一直想看malloc的原理,在搜了好几篇malloc源码后遂放弃,晦涩难懂。 后来室友买了本深入理解计算机系统的书,原来上面有讲malloc的原理,遂看了,先明白理论,在看代码就理解比较快了= = 1.问题的引入: 为什么要使用malloc,主要是因为在代码中,为了节约内存,很多数据都是动态生成的,所以会用malloc,对应于C++中的new,底层还是调用malloc. 2.碎片的问题: 会有内部碎片与外部碎片的问题,内部碎片难以消除(因为字对齐之类的问题),而外部碎片是可以消除的(如果不消除的话,外部的内存块越来越小,虽然数量多了,但是利用率会急剧下降!) 3.需...
阅读全文
摘要://位图的概念就是在个一字节八位的地方存八个状态比如 bool hash[] 表示某个数字被标记过,一个数字需要一个字节而bitMap就是可以把每位都用来标记,起到节约空间的目的//位图的概念就是在个一字节八位的地方存八个状态#includechar s[100]; // 范围0~799void bitmap(int n){ int insert=n/8; int insertbit=n%8; s[insert]|=(1<<insertbit);}int findBitmap(int n){ int insert=n/8; int insertbit=n%8; ...
阅读全文
摘要:1. 编译器的优化在本次线程内, 当读取一个变量时,为提高存取速度,编译器优化时有时会先把变量读取到一个寄存器中;以后,再取变量值时,就直接从寄存器中取值;当变量值在本线程里改变时,会同时把变量的新值copy到该寄存器中,以便保持一致。当变量在因别的线程等而改变了值,该寄存器的值不会相应改变,从而造成应用程序读取的值和实际的变量值不一致。当该寄存器在因别的线程等而改变了值,原变量的值不会改变,从而造成应用程序读取的值和实际的变量值不一致。2.volatile应该解释为“直接存取原始内存地址”比较合适,“易变的”这种解释简直有点误导人。加上volatile 实际上就直接从内存中读取,避免了被编译
阅读全文
摘要:实践出真理!#include#includeclass A{public:A(); virtual~A(); virtual void fun1(){ printf("A:fun1"); } virtual void fun2(){ printf("A:fun2"); }};A::A(){}A::~A(){ printf("Delete class A\n");}class B : public A{public:B(); ~B(); void fun1(){ ...
阅读全文
摘要:1.构造函数能否声明为虚函数: 构造函数不能声明为虚函数,虚函数对应一个vptr,可是这个vptr其实是存储在对象的内存空间的。问题出来了,如果构造函数是虚的,就需要通过 vptr来调用,可是对象还没有实例化,也就是内存空间还没有,怎么找vptr呢?所以构造函数不能是虚函数。(而且现在VS的编译器一般也会报错)。2.析构函数能否声明为虚函数:析构函数可以声明为虚函数,而且有时是必须声明为虚函数,是因为删除指向派生类的基类指针的时候,如果析构函数不是虚函数,派生类的析构函数将不会被执行,直接后果的内存泄漏!!!3.能否在构造函数里面调用虚函数:编译不会报错,但是最好不要这样做!在调用构造这时候类
阅读全文
摘要:#include#includeusing namespace std;class base1{public: base1(){ printf("start base1\n"); } ~base1(){ printf("end base1\n"); }private: int mx,my; int mi,mj;};class base2:public base1{public: base2(){ printf("start base2\n"); } ~base2(){ ...
阅读全文
摘要:析构函数的作用与构造函数正好相反,是在对象的生命期结束时,释放系统为对象所分配的空间,即要撤消一个对象。用对象指针来调用一个函数,有以下两种情况:如果是虚函数,会调用派生类中的版本。(在有派生类的情况下)如果是非虚函数,会调用指针所指类型的实现版本。析构函数也会遵循以上两种情况,因为析构函数也是函数嘛,不要把它看得太特殊。 当对象出了作用域或是我们删除对象指针,析构函数就会被调用。当派生类对象出了作用域,派生类的析构函数会先调用,然后再调用它父类的析构函数, 这样能保证分配给对象的内存得到正确释放。但是,如果我们删除一个指向派生类对象的基类指针,而基类析构函数又是非虚的话, 那么就会先调用基类
阅读全文
摘要:105 6 7 8 9 10 1 2 3 4查找4当是s[ll]s[mid]的时候,(k>s[ll]||k#includeusing namespace std;int s[109];int main(){ int n,k; while(scanf("%d",&n)!=EOF){ int i; for(i=0;i=s[ll]||k<=s[mid]){ rr=mid-1; }else{ ll=mid+1; } ...
阅读全文
摘要:给一个长度为n的字符串,把这个字符串循环右移N位(0#includeusing namespace std;int s[109];int main(){ int n,k; while(scanf("%d",&n)!=EOF){ int i; for(i=0;i<n;i++){ scanf("%d",&s[i]); } scanf("%d",&k); k=k%n; int end1=(k-1)/2; int end2=(k+n-1)/2; int en...
阅读全文
摘要:char const* ptr1const char * ptr2char * const ptr3看到这三个const作何感想其实const比较好理解的是const 后面整体是不能改变的(整体的思想)如char const* ptr1=&s;后//*ptr1=‘B’;这样是不可以,但是ptr1=&s2;还是可以的;const char * ptr2同理char * const ptr3=&s;后*ptr3='A';是可以的,但是ptr3=&s2;不行
阅读全文
摘要:sizeof一个类的时候,都什么会被计算?静态成员会被计算进来么?如果这是一个子类,它的父类成员会被计算么?#include using namespace std;class Base1 {public: int b1; static int a1; virtual void f() { cout << "Base1::f" << endl; } virtual void g() { cout << "Base1::g" << endl; } void h() { cout << "
阅读全文
摘要:1.指针可以不初始化,引用必须要初始化。2.指针可以改变指向,引用在初始化后就不能再变化了。#includevoid swap1(int& a,int& b){ int temp; temp=a;a=b;b=temp;}void swap2(int *a,int *b){ int temp; temp=*a; *a=*b; *b=temp;}int main(){ int x=1,y=10; swap1(x,y); swap2(&x,&y); printf("%d %d\n",x,y);}在swap1处:可以发现,在main函数中,x...
阅读全文
摘要:假如有列表:books = [ {"name":"C#", "price":23.7, "store":"amaing"}, {"name":"ASP.NET", "price":44.5, "store":"amaing"}, {"name":"C#", "price":24.7, "store":"dd&
阅读全文
|