计算机视觉
图像处理

总结系列_4(C++知识学习,续…)

  1. Windows的 窗体交互是基于消息映射机制的,比如我们的编辑框可以映射一个变量,我们在编辑框里输入一个数字后,这个数据就可以传递到映射变量里;而我们的按钮可以映 射成一个函数,当我们运行的窗体点击这个按钮时,相应的映射函数就被执行。映射变量的添加在类向导里面。而映射函数的添加比较方便,只需要在资源预览中双 击按钮控件,便会弹出一个Add Member FunC++tion的对话框。
  2. VC中调用延时函数为Sleep(int n),其中的S一定要大写,且n为毫秒的单位。必须包含头文件<<windows.h>>。
  3. 普通的代码即使没有用到类,但是.c和.c++区别还是蛮大的。比如在.c中(VC++6.0软件)变量的定义要在mian函数括号中的前面,如果在某些赋值语句的后面的话就有可能编译通不过。但是在.cpp文件中,变量定义放在中间是可以的。
  4. 如果程序的.exe文件要运行,并且需要调用相对路径的文件,则此时的相对路径不是针对Debug而言的,而是针对.c文件所在的目录而言的。
  5. 如果库函数的参数有默认的值的话并且这几个参数是在函数后面,则我们可以不输入参数,即默认了值。
  6. 凡是用new分配内存的对象均是在堆中定义的。对于在堆中分配的对象来说,如果程序中不显式地析构该对象,那么该对象的生命周期将与应用程序的生命周期是一致的。
  7. 程序中每一个对话框资源都需要一个类而之对应。
  8. 当用类调用函数时用::号,当用对象调用其函数时用.号。
  9. 静态文本框的ID如果不改变的话,则几个文本框的可以相同不会冲突。但是在ClassWizard就看不到它们的ID。如果改变的话则可以看到相应的ID。对于函数参数是否需要传入地址来说,比如int DrawText( const CString& str, LPRECT lpRect, UINT nFormat );第一个需要一个字符串指针,第二个也是一个指针。当然类的对象不可以表示一个指针(如果直接传递类对象说明可能重载了类型转换的操作符),但是结构体对象不能表示指针?
  10. 对一个变量进行自加或减操作前,一定要初始化这个变量。否则,结果是不确定的。
  11. 资源ID号确定的潜规则,IDM表示菜单资源,IDC表示光标资源,IDI表示图表资源。
  12. 在MFC单文档中的应用程序类App和文档类Doc都不是从CWnd类派生来的,所以没有MessageBox等一系列函数。因为文档类和应用程序类是从CCmdTarget类派生来的,所以可以接受命令消息和通告消息,但是不能接受标准消息。
  13. 解决0导航中类消失的方法,先把工程关了,然后把.ncb文件删掉。最后重新打开工程即可。
  14. 视类窗口始终是覆盖在框架窗口之上的,框架窗口接收不到鼠标消息。
  15. 应用程序实例是由实例句柄来标识的。而对MFC程序来说,通过产生一个应用程序类的对象来唯一标识应用程序的实例。每个MFC程序有且仅有一个从应用程序类派生的类。每一个MFC程序实例有且仅有一个该派生类的实例化对象,也就是theApp全局对象。该对象就表示了应用程序本身。
  16. 数据的存储和加载由文档类来完。成,数据的显示和修改则由视类来完成,从而把数据管理和显示方法分离开来。文档/视结构是MFC程序的一个重点。窗口类对象和窗口不是一回事,他们之间唯一的关系是窗口类对象内部定义了一个窗口句柄变量,保存了与这个窗口类对象相关的那个窗口句柄。所以窗口销毁,窗口类不一定销毁,窗口类销毁窗口就一定销毁了。
  17. 凡是以Afx开始的函数都是应用程序框架类函数,也就是全局函数,在程序的所有类中都可以直接调用。
  18. 窗口的类名即lpszClass可以作为不同窗口的身份识别标志。
  19. 在MFC程序中,如果想要修改应用程序窗口的图标,则应在框架类中进行,因为在框架窗口中才有标题栏,所以才能修改位于该标题栏上的图标;如果想要修改程序窗口的背景和光标,就应该在视类中进行。
  20. 有时候函数的参数是类的对象指针,但是传递的是类的对象名,则有可能是它选择的是对象的构造方法进行的隐式转换,或者是重载了其它的操作符。
  21. 在c语言中结构体中不能够有成员函数,但是在c++中可以有。
  22. 结构体默认的情况下,其成员是公有的,类默认的情况下,其成员是私有的。
  23. 当用类定义一个对象时,如果要对对象中的成员变量赋值,那么这个成员变量必须是公有的。也就是说类中的私有变量只有在类的内部实现代码中可以用。一旦构造了一个对象后就应该看不到这个变量了。
  24. C++重 载时所需要的条件:函数的参数类型,参数个数不同,才能构成函数的重载。因此,当只有函数的返回值类型不同时是不能构成函数的重载的。另外,为了防止调用 函数的歧义,要主要函数带有默认参数的这种情况。所以,函数的重载指的是函数的名称是一样的,但是函数实现的功能一般都不一样。
  25. 变量的可见性是指当这个变量为函数的一个参数时,那么在这个函数的内部所有出现该变量的地方都默认为来自这个函数的传入参数。
  26. 当子类在继承父类时,如果父类的构造函数中带有参数,但子类自己的构造函数中没有带有参数,那么子类继承的过程中,应该在构造函数后面加:号,然后调用父类构造函数,并与此同时传递参数进去。
  27. Public定义的成员可以在任何地方被访问。Protected定义的成员只能在该类及其子类中访问,private定义的成员只能在该类自身中被访问。类的继承中默认的方式为private继承。基类中的private成员不能被派生类访问,因此,private成员不能被派生类所继承。
  28. 可以把一个子类对象赋给一个父类指针,不用程序员进行强制类型转换,程序内部会自动帮转换。但是不能够反过来复赋值。
  29. C++的多态性是指在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数。如果对象类型是派生类就调用派生类的函数。如果对象类型是基类,就调用基类的函数。它是采用的迟邦定技术实现的。
  30. 纯虚函数是指标名为不具体实现的虚成员函数。凡是含有纯虚函数的类叫做抽象类,这种类不能声明对象,只是作为基类为派生类服务。并且在派生类中必须完全实现基类的纯虚函数,否则派生类也变成了抽象类,不能实例化对象。
  31. 函数覆盖的条件:基类函数必须是虚函数,且发生覆盖的两个函数要分别位于派生类和基类中,函数的名称与参数列表必须完全相同。
  32. 函数隐藏的条件:如果基类函数使用了虚函数,但是派生类的函数虽然与基类的函数同名,但参数列表不同,这时候是函数的隐藏。另一种情况是基类没有使用虚函数,但是派生类的函数与基类的函数完全相同,这时也是隐藏。
  33. 引用必须在申明时初始化。引用的地址没有任何意义,因为引用的地址就是它所引用的变量或者对象的地址,对引用的地址所做的操作就是对被引用的变量或对象的地址所做的操作。
  34. inline 关键字用来定义一个类的内联函数,引入它的主要原因是用它替代C中表达式形式的宏定义。
  35. C++中用一个冒号:表示派生类从基类中派生,用2个冒号::表示类中具体成员函数的实现或者说使用双冒号前面的命名空间。
  36. 关于重载一定要注意:重载函数的参数类型和参数个数一定要不同(即:要么参数的类型不同,要么参数的个数不同,要么参数的类型和个数都不同),否则,编译器就不知道该调用那个函数了。
  37. C/C++语言中auto表示为自定义变量,即只在模块内部生效,出了模块就没有用了,与static变量功能相反。一般C语言中定义的变量,如果没有特别声明的话都是auto变量,如果加了auto就说明与普通变量是一样的。
  38. 命名空间的作用可以从字面意思来理解,主要是为了解决名字冲突的问题而提出来的。因为不同人写不同的函数或者库时有可能采用同样的名字,所以每个人在写一个源文件时可以用自己的命名空间,在别人调用你的函数时只需要在前面加一个你的命名空间即可。
  39. 类模板是对一批批成员数据类型不同类的抽象。程序员只要为这一批类所组成的整个类家族创建一类模板,就可以用来生产许多具体的类。所以说类是对象的抽象,而类模板又是类的抽象。
  40. typedef struct的作用。看下面例子:

typedef struct my_struct {

int a;

int b;

int c;

}num_3;

该语句有2个功能,首先定义了my_struct结构体,所以以后如果需要用这个结构体来定义变量的话,需要这样用struct my_struct a;有2个不方便,其一是my_struct前面需要加一个struct关键字;其二是my_struct这个名字固定,不能从名字字面上体现出其意义;如果用了typedef的话,这2个不方便都可以解决,想必到这里大家都明白了。

  1. 头文件编译器一般不单独进行编译的,即使其内部有语法错误。只有该头文件被源文件include时其才会检查其语法错误。
  2. 在vs2010中,如果头文件是自己建立的,反正工程目录下的话,则源文件包含头文件时,需要用” ”,不能用<>,否则报错,无语了!
  3. C++中引用是一个变量的别名,定义时需要初始化,通过更改别名的值达到更改变量值的目的,引用名一旦建立,不能再重新定义相同的引用名。如果是常引用的话,则应用名作为一个常量的别名,此时不能对引用名进行赋值操作。下面博文中讲了引用和指针的区别和联系http://www.cnblogs.com/skynet/archive/2010/09/22/1832911.html. 当引用作为参数传递时,如果不是常量引用,则调用该函数时,传递参数需要传入变量值,不能传入常量值,只能传入相应数据类型的变量值。如果是常量引用,则传入常量值和变量值都可以。
  4. 将string类转换成char *的常用方法为:

string str;

const char *str1;

str1=str.c_str();

这在读取图像文件名时很有用,因为如果用cvLoadImage()的话括号里面的参数只能为const char*型,而一般对文件名的读取都是用string类,这样比较灵活。

  1. 当函数的返回类型为引用时,这时的返回值不能为函数内部的局部变量,因为函数结束后其局部变量已被析构,因此对应的引用也就不存在。
  2. for 循环后面的那个变量如果是自加的话,先加或后加的效果是一样的。比如说下面的代码其括号内和括号外的输出完全一样:

#include <iostream> using namespace std; int main( int argc, unsigned char ** ) { int i , j; for( i = 0; i < 10; i++ ) { // cout<<i<<endl; } cout<<i<<endl<<“next:”<<endl; for( j = 0; j < 10; ++j ) { // cout<<j<<endl; } cout<<j<<endl<<“end!”<<endl; return 1; }

  1. 关于const的常见用法:

a:

int me;

const int * p1=&me;//p1可变,*p1不可变,此时不能用*p1来修改,但是p1可以转向

int * const p2=&me;//p2不可变,*p2可变,此时允许*p2来修改其值,但是p2不能转向。

const int *const p3=&me;//p3不可变,*p3也不可变,此时既不能用*p3来修改其值,也不能转向

b:

限定函数的传递值参数:

void function(const int Var); //传递过来的参数在函数内不可以改变.

c. 类中的const放在函数后,表示该函数内部不会修改类中的数据变量,这样的函数称为const常量函数。

  1. typedef 和 #define的用法后面目标的顺序是反的.typedef A B 可以理解为把A赋给B; define A B可以理解为把B 赋给A.
  2. 变量初始化时可以用括号对其进行赋值,比如说int a(10);
  3. 在类中,冒号初始化是给数据成员分配内存空间时就进行初始化,主要用在对类中的引用变量,const常量,引用对象时。对于在函数中初始化,是在所有的数据成员被分配     内存空间后才进行的。关于2者的区别,http://www.cppblog.com/luyulaile/archive/2011/02/14/140059.html中作了较详细的介绍。
  4. 关于c++中类和结构体的区别,有网友简单总结如下:

(1)class中默认的成员访问权限是private的,而struct中则是public的。

(2)从class继承默认是private继承,而从struct继承默认是public继承。

除此这外无任何区别。

  1. vector类型的数据可以直接用等号进行copy,即可以这样赋值。
  2. pair和map的区别:map是一个容器,容器中的第一个元素表示的是键值key,其它元素分别表示以后用该 容器存储数据时的数据类型。因此map中的每一条记录的key值是不能重复的。当map定义的时候只有2个集合的时候,里面的每一条记录可以用pair来 存储。因此可以简单的理解一个pair对应的是一条具体的记录,而一个map是一个存放pair的容器,并且map声明了容器的属性。

当在进行pair数据类型的定义时,如果其元素中的一个已经确定,另一个还不知道,则在定义的同时可以直接传入确定的那个元素,另一个用它的数据类型后面接一个空括号即可。

  1. 在使用vector时,必须是已存在的元素才能用下标操作符进行索引。可以使用at和[]获取指定位置的数据或者给指定位置的数据赋值。
  2. 引用作为函数的返回值时,函数的返回值可以理解为函数返回了一个变量(事实上,函数返回引用时,它返回的是一个指向返回值的隐式指针),因此,值为引用的函数可以用作赋值运算符的左操作数。另外,用引用返回一个函数值的最大好处是,在内存中不产生被返回值的副本。
  3. 一般类的构造函数中初始化私有变量的值,而初始化函数中一般是定义一些全局变量并赋值什么的。
  4.  类中关于函数中的默认参数是在函数声明部分体现的。
  5.  如果一些函数需要默认值的话,可以直接在函数定义的时候指定,该指定并不一定是具体的某个值,也可以是空值等等。另外在函数内部实现时,有时候要注意默认值的特殊性。

转载注明来源:CV视觉网 » 总结系列_4(C++知识学习,续…)

分享到:更多 ()
扫描二维码,给作者 打赏
pay_weixinpay_weixin

请选择你看完该文章的感受:

0不错 0超赞 0无聊 0扯淡 0不解 0路过

评论 3

评论前必须登录!