当前位置:  编程技术>c/c++/嵌入式
本页文章导读:
    ▪MFC对话框添加菜单栏并添加鼠标单击响应(实例,包你一学就会)      转自:http://blog.163.com/qiubing555@yeah/blog/static/161669431201136560948/1,添加一个资源,选择menu;2,在菜单中写入自己的菜单选项,如关于  版本 等信息 添加菜单项:关于   版权  想你.........
    ▪FFLIB之FFLUA——C++嵌入Lua&扩展Lua利器      摘要:在使用C++做服务器开发中,经常会使用到脚本技术,Lua是最优秀的嵌入式脚本之一。Lua的轻量、小巧、概念之简单,都使他变得越来越受欢迎。本人也使用过python做嵌入式脚本,二者各.........
    ▪c++对象内存模型【内存布局】      #类中的元素0. 成员变量   1. 成员函数   2. 静态成员变量   3. 静态成员函数   4. 虚函数   5. 纯虚函数#影响对象大小的因素0. 成员变量   1. 虚表指针 .........

[1]MFC对话框添加菜单栏并添加鼠标单击响应(实例,包你一学就会)
    来源:    发布时间: 2013-10-17

转自:http://blog.163.com/qiubing555@yeah/blog/static/161669431201136560948/

1,添加一个资源,选择menu;

2,在菜单中写入自己的菜单选项,如关于  版本 等信息

 

添加菜单项:关于   版权  想你了  ID:xiangni  等信息

3  将菜单加入对话框,即可显示。

方法:打开对话框,右键属性,选择刚才的菜单即可。

———————————————分割线,下面就加入单击时的鼠标响应

 

1,将菜单加入类

  鼠标单击菜单选项,加入要显示的类,这里选择已有的类,选择要添加的对话框的类

2比如这里选择要显示的对话框的类:C***App

 

 

3 在对话框初始化函数中添加加载菜单的命令,应该称作是加载菜单栏吧

 

 

 

 

工作空间转到类视图,选择C***Dlg类,单击,在下面找到初始化函数OnInitDialog(),双击到其位置,添加下面的代码(粗体部分)

 

BOOL CJianpDlg::OnInitDialog()

{

CDialog::OnInitDialog();

// Add "About..." menu item to system menu.

CMenu* menu =new CMenu;

menu->LoadMenu(MAKEINTRESOURCE(IDR_MENU1));      //红色部分为对应自己添加的菜单资源的名称

this->SetMenu(menu);

// IDM_ABOUTBOX must be in the system command range.

ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

ASSERT(IDM_ABOUTBOX < 0xF000);

4  为 关于  菜单项添加消息映射:单击时弹出关于对话框

方法:单击  关于 菜单项,建立类向导,并在类向导中添加 Command Message,编辑代码如下:  

为  关于  菜单项 添加响应代码

单击  EditCode  编辑代码:

 

void CJianpApp::OnAbout() 

{

// TODO: Add your command handler code here

CDialog* dlg = new CDialog;

dlg->Create(MAKEINTRESOURCE(IDD_ABOUTBOX));        //红色部分为对应菜单项的ID

dlg->ShowWindow(1);

}

 

说明:粗体为添加代码,其余部分为向导自动生成代码。

本文链接


    
[2]FFLIB之FFLUA——C++嵌入Lua&扩展Lua利器
    来源:    发布时间: 2013-10-17

摘要:

在使用C++做服务器开发中,经常会使用到脚本技术,Lua是最优秀的嵌入式脚本之一。Lua的轻量、小巧、概念之简单,都使他变得越来越受欢迎。本人也使用过python做嵌入式脚本,二者各有特点,关于python之后会写相关的文章,python对于我而言更喜欢用来编写工具,我前边一些相关的算法也是用python来实现的。今天主要讲Lua相关的开发技术。Lua具有如下特点:

  • Lua 拥有虚拟机的概念,而其全部用标准C实现,不依赖任何库即可编译安装,更令人欣喜的是,整个Lua 的实现代码并不算多,可以直接继承到项目中,并且对项目的编译时间几乎没有什么影响
  • Lua的虚拟机是线程安全的,这里讲的线程安全级别指得是STL的线程安全级别,即一个lua虚拟机被一个线程访问是安全的,多个lua虚拟机被多个线程分别访问也是安全的,一个lua虚拟机被多个线程访问是不安全的。
  • Lua的概念非常少,数据结构只有table,这样当使用Lua作为项目的配置文件时,即使没有编程功底的策划也可以很快上手编写。
  • Lua没有原生的对象,没有class的关键字,这也保障了其概念简单,但是仍然是可以使用Lua面向对象编程的。
  • Lua尽管小巧,却支持比较先进的编程范式,lua 中的匿名函数和闭包会让代码写起来更加 优雅和高效,如果某人使用的C++ 编译器还比较老套,不支持C++11,那么可以尽快感受一下lua的匿名函数和闭包。
  • Lua是最高效的嵌入式脚本之一(如果不能说最的话,目前证据显示是最)。
  • Lua的垃圾回收也可以让C++程序收益匪浅,这也是C++结合脚本技术的重要优势之一。
  • Lua 的嵌入非常的容易,CAPI 相对比较简洁,而且文档清晰,当然Lua的Capi需要掌握Lua中独特的堆栈的概念,但仍然足够简单。
  • Lua的扩展也非常的容易,将C++是对象、函数导入到lua中会涉及到一些技巧,如果纯粹使用lua CAPI会稍显繁杂,幸运的是一些第三方库简化了这些操作,而FFLUA绝对是最好用的之一。

嵌入Lua:

嵌入lua脚本,必须要把lua脚本载入lua虚拟机,lua中的概念称之为dofile,FFLUA中封装了dofile的操作,由于lua文件可能集中放在某个目录,FFLUA中也提供了设置lua脚本目录的接口:

int add_package_path(const string& str_)
int load_file(const string& file_name_) throw (lua_exception_t)

load_file就是执行dofile操作,若出错,则throw异常对象,可以使用exception引用目标对象使用what接口输出代码出错的traceback。

当嵌入lua时,最简单的情况是把lua脚本当成配置使用,那么需要获取lua脚本中的变量和设置lua变量,FFLUA封装了两个接口用于此操作。lua是动态语言,变量可以被赋值为任何lua支持的类型,但C++是强类型的,所以两个接口都是范型的:

template<typenameT>
int get_global_variable(conststring& field_name_, T& ret_);
template<typenameT>
int get_global_variable(constchar* field_name_, T& ret_);

有时需要直接执行一些lua语句,lua中有dostring的概念,FFLUA中封装了单独的接口run_string:

void run_string(constchar* str_) throw (lua_exception_t)

嵌入lua时最一般的情况是调用lua中的函数,lua的函数比C++更灵活,可以支持任意多个参数,若未赋值,自动设置为nil,并且可以返回多个返回值。无论如何,从C++角度讲,当你嵌入lua调用lua函数时,你总希望lua的使用方式跟C++越像越好,你不希望繁复的处理调用函数的参数问题,比如C++数据转换成lua能处理的数据,即无趣又容易出错。正也正是FFLUA需要做到,封装调用lua函数的操作,把赋值参数,调用函数,接收返回值的细节做到透明,C++调用者就像调用普通的C++函数一样。使用FFLUA中调用lua函数使用call接口:

void call(constchar* func_name_) throw (lua_exception_t)

当调用出错时,异常信息记录了traceback。

实际上,FFLUA重载了9个call函数,以来自动适配调用9个参数的lua函数。

template<typename RET>
RET call(const char* func_name_) throw (lua_exception_t);
......
template<typename RET, typename ARG1, typename ARG2, typename ARG3, typename ARG4,
typename ARG5, typename ARG6, typename ARG7, typename ARG8, typename ARG9>
RET call(const char* func_name_, ARG1 arg1_, ARG2 arg2_, ARG3 arg3_,
ARG4 arg4_, ARG5 arg5_, ARG6 arg6_, ARG7 arg7_,
ARG8 arg8_, ARG9 arg9_) throw (lua_exception_t);

需要注明的是:

  • call接口的参数是范型的,自动会使用范型traits机制转换成lua类型,并push到lua堆栈中
  • call接口的返回值也是范式的,这就要求使用call时必须提供返回值的类型,如果lua函数不返回值会怎样?lua中有个特性,只有nil和false的布尔值为false,所以当lua函数返回空时,你仍然可以使用bool类型接收参数,只是调用者忽略其返回值就行了。
  • call只支持一个返回值,虽然lua可以返回多个值,但是call会忽略其他返回值,这也是为了尽可能像是调用C++函数,若要返回多个值,完全可以用table返回。

扩展LUA:

这也是非常重要的操作,嵌入lua总是和扩展lua相伴相行。lua若要操作C++中的对象或函数,那么必须先把C++对应的接口注册都lua中。Lua CAPI提供了一系列的接口拥有完成此操作,但是关于堆栈的操作总是会稍显头疼,fflua极大的简化了注册C++对象和接口的操作,可以说是最简单的注册方式之一(如果不准说最的话)。首先我们整理一下需要哪些注册操作:

  • C++ 静态函数注册为lua中的全局函数,这样在lua中调用C++函数就像是调用C++全局函数
  • C++对象注册成Lua中的对象,可以通过new接口在lua中创建C++对象
  • C++类中的属性注册到lua,lua访问对象的属性就像是访问table中的属性一样。
  • C++类中的函数注册到lua中,lua调用其接口就像是调用talbe中的接口一样。

FFLUA中提供了一个范型接口,适配于注册C++相关数据:

template<typename T>
void fflua_t::reg(T a)
{
a(this->get_lua_state());
}

这样,若要对lua进行注册操作,只需要提供一个仿函数即可,这样可以批量在注册所有的C++数据,当然FFLUA中提供了工具类用于生成仿函数中应该完成的注册操作:

template<typename CLASS_TYPE = op_tool_t, typename CTOR_TYPE = void()>
class
    
[3]c++对象内存模型【内存布局】
    来源:    发布时间: 2013-10-17

#类中的元素

0. 成员变量   1. 成员函数   2. 静态成员变量   3. 静态成员函数   4. 虚函数   5. 纯虚函数

#影响对象大小的因素

0. 成员变量   1. 虚表指针   2. 虚表偏移   3. 内存对齐

#对象内存布局分类讨论

vc6变量查看器中(Locals,Watch1等),也可以看到部分对象布局的情况(不完整,且虚继承是错误的)。

vs2005及以后版本的编译器提供了/d1reportSingleClassLayout[类名]编译选项来查看对象完整的内存布局:

1 cl classLayout.cpp /d1reportSingleClassLayoutCChildren

0. 单一类

(1). 空类

sizeof(CNull)=1(用于标识该对象)

(2). 只有成员变量的类

int nVarSize = sizeof(CVariable) = 12

 

内存布局:

(3). 只有虚函数的类

int nVFuntionSize = sizeof(CVFuction) = 4(虚表指针)

 

内存布局:

(4). 有成员变量、虚函数的类

 

int nParentSize = sizeof(CParent) = 8

内存布局:

1. 单一继承(含成员变量、虚函数、虚函数覆盖)

int nChildSize = sizeof(CChildren) = 12

vc中显示的结果(注:还有1个虚函数CChildren::g1没有被显示出来):

d1reportSingleClass查看:

内存布局:

2. 多继承 (含成员变量、虚函数、虚函数覆盖)

int nChildSize = sizeof(CChildren) = 20

vc中显示的结果(注:还有2个虚函数CChildren::f2,CChildren::h2没有被显示出来,this指针的adjustor值也没打印出):

d1reportSingleClass查看:

内存布局:

3. 深度为2的继承(含成员变量、虚函数、虚函数覆盖)

 

int nGrandSize = sizeof(CGrandChildren) = 24

vc中显示的结果(注:还有3个虚函数CGrandChildren::f2,CChildren::h2,CGrandChildren::f3没有显示出来,this指针的adjustor值也没打印出):

d1reportSingleClass查看:

内存布局:

4 重复继承(含成员变量、虚函数、虚函数覆盖)

 

int nGrandSize = sizeof(CGrandChildren) = 28

vc中显示的结果(注:还有大量的虚函数没有显示出来,this指针的adjustor值也没打印出):

d1reportSingleClass查看:

内存布局:

由于m_nAge在内容中存在两个拷贝,因此我们不能直接通过pGrandChildrenA->m_nAge来访问该变量,

这样会存在二义性,编译器无法知道应该访问CChildren1中的m_nAge,还是CChildren2中的m_nAge。

为了标识唯一的m_nAge,就需要带上其所在范围的类名了。如下:

1 pGrandChildrenA->CChildren1::m_nAge = 1;
2 pGrandChildrenA->CChildren2::m_nAge = 2;

5. 单一虚继承(含成员变量、虚函数、虚函数覆盖)

 

int nChildSize = sizeof(CChildren) = 20

d1reportSingleClass查看:

内存布局:

 

6. 多虚继承(含成员变量、虚函数、虚函数覆盖)

(1) virtual CParent1, CParent2

int nChildSize = sizeof(CChildren) = 24

d1reportSingleClass查看:


    
最新技术文章:
▪C++单例模式应用实例
▪C++设计模式之迭代器模式
▪C++实现动态分配const对象实例
▪C++设计模式之中介者模式
▪C++设计模式之备忘录模式
▪C++插入排序算法实例
▪C++冒泡排序算法实例
▪C++选择排序算法实例
▪C++归并排序算法实例
▪C++设计模式之观察者模式
▪C++中复制构造函数和重载赋值操作符总结
▪C++设计模式之状态模式
▪C++设计模式之策略模式
▪C++设计模式之访问者模式
▪C++设计模式之模板方法模式
▪C++实现下载的代码
▪C++模板之特化与偏特化详解
▪C++实现查壳程序代码实例
▪C语言、C++内存对齐问题详解
▪C语言、C++中的union用法总结
▪C++基于CreateToolhelp32Snapshot获取系统进程实例
▪C++中memcpy和memmove的区别总结
▪C++通过TerminateProess结束进程实例
▪C++内存查找实例
▪C++实现CreatThread函数主线程与工作线程交互的...
▪C++设计模式之桥接模式
▪C++中关键字Struct和Class的区别
▪C++设计模式之组合模式
▪C++ COM编程之什么是组件?
▪C++ COM编程之什么是接口?
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3