随笔 - 55  文章 - 15  trackbacks - 0
<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

常用链接

留言簿

随笔分类

随笔档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜

     摘要: 线程的大概了解和ZThread库的安装配置。  阅读全文
posted @ 2012-05-14 18:03 Dino-Tech 阅读(760) | 评论 (0)编辑 收藏
     摘要: 模板的偏特化注意要点。就是要注意特化的时候一定要在类后面跟<>里面写上特定的类型。  阅读全文
posted @ 2012-05-08 19:23 Dino-Tech 阅读(248) | 评论 (0)编辑 收藏
     摘要: 利用模板和函数指针实现C++下的event事件处理机制。  阅读全文
posted @ 2012-04-26 17:52 Dino-Tech 阅读(615) | 评论 (0)编辑 收藏
  1. 继承中的函数隐藏
         任何时候重新定义了基类中的一个重载函数,那么在新类中的所有其他版本将被自动隐藏。修改返回值和参数同样会隐藏基类其他版本的函数,如果该函数是虚函数,不能在新类中修改返回值。

2. 自动类型转换方法(该转换只发生在函数调用期间)
    1) 利用转型构造函数
    2) 利用运算符转换
   如果不想自动转换,可将转型构造函数利用explicit关键字设为显式调用
 
class One

public:
   One()
{}
}
;
class Two
{
public:
   
explicit Two(const& One){}
}
;
void f(Two){}
int main()
{
  One one;
  f(one);
// error
  f(Two(one));//right
  return 0;
}

It's supposed to help with your complexion.

运算符转换之前没用到过,该方法的中心思想是,在该类中添加一个 operator Type()的函数,该函数没有返回值,要从该类转型到该Type类型的时候,编译器会自动调用该成员函数,转换成Type类型

class Four
{public:
operator Three() const
{
return Three(x);
}

}
;
g(Three)
{}
int main()
{
Four four;
g(four);
//invoke four.Three(), there no return value
return 0;
}

3. 拷贝构造函数和赋值操作符
    子类如果没有写这两个,编译器将会自动生成,生成的代码中调用父类的拷贝构造函数和赋值操作符,所以如果我们自己写的话,最好也要调用父类的拷贝构造函数和赋值操作符。
    因为构造函数和operator=和拷贝构造函数只负责初始化自己层次的构造,所以要完成初始化,必须先要初始化父类,所以他们不能被继承。(其实没理解这句话,如果被继承了的话,那子类就可以负责完成父类的初始化了???)
    一旦我们自己决定手动添加拷贝构造函数和operator=,编译器会假定我们已经知道所作的一切,并且不再自动调用基类版本,如果想调用,必须我们自己添加,即初始化列表。

4. 多态的进化(为什么使用多态和怎么用)
....


1
posted @ 2012-04-23 17:33 Dino-Tech 阅读(205) | 评论 (0)编辑 收藏
     摘要: 我们知道,在c++中,编译器一定要初始化一个类对象之后才能对其进行操作,使用malloc动态分配内存给对象之后,还要记得一定要初始化它,不然,这个对象就没办法用,而且很多人只关注类的功能,而不往往会忘掉初始化,这是bug的一个重要来源。所以c++想把分配内存和初始化这两份工作一块让编译器处理了,不用我们程序员惦记着。  阅读全文
posted @ 2012-04-20 21:07 Dino-Tech 阅读(219) | 评论 (0)编辑 收藏
原文链接:http://www.codeproject.com/Articles/633/Introduction-to-COM-What-It-Is-and-How-to-Use-It 
COM是个啥?



是一个可以跨语言跨进成的二进制复用方法。不同于C++的模板和继承是源代码级别的复用,COM是二进制级别的。windows下服用二进制代码的例子就是dll文件。但是之前这些dll的接口都是用c写的,所以只有c语言能够明白这些接口,vb都不行。
COM通过定义二进制标准来解决这些问题。COM指定这些DLL或者EXE必须按特定的结构在内存中进行组织。并且,这些二进制代码与语言不相关。一旦这么做了,那么用不同的语言访问这些二进制代码将变成现实。
由于COM对象在内存中的结构碰巧同那些用c++虚函数编写的结构相同,所以,很多COM代码用C++来些,但是记住COM其实是语言无关的。






COM基本概念


1. 接口类: 一组函数或者方法。一般是抽象类,方法全部为纯虚函数。作为父类,提供服务。接口类一般以I开头,例如IShellLink。接口可以从其他接口继承,接口的继承是单根继承模式,即从一个IUnknown继承而来。不允许多重继承,有点像Java。
2. coclass类(component object class)包含在一个DLL或者一个EXE文件中,继
承一个或多个接口,具体实现这些接口。



3. COM对象:一个coclass类在内存中的实例。


4. COM服务器:提供coclass的二进制文件(DLL或EXE),包含一个或多个coclass类。


要想提供服务,该COM服务器必须注册到本地的注册表中,也就是说,这个COM服务器放在了哪里,可以在那个文件目录下找到。每个COM服务器都可以在注册表中找到。
那么整个的层次结构应该是: 


GUID(Globally Unique identifier)128位数,因为是个数值,所以是语言无关的。每个接口类和coclass都有一个GUID,而且全球唯一。
CLSID 是coclass 的GUID

IID是接口类的GUID

有两个原因使得GUID在COM中被广泛应用
1. 只是一个数值,每个编程语言都可以处理。
2. 每个被创建的GUID都是唯一的。因此,COM开发者可以穿件自己的GUID而不会同别人相同。









5. HRESULT: 一个整形,是返回值。

6. COM库是操作系统的一部分,当你在做COM相关的工作时,会和它交互。



开动:



先看看COM和C++的不同:





1. 创建新对象: C++ operator new 在堆上创建,或者在栈上创建
                      COM,调用COM库中的API函数创建



2. 删除对象:    C++ operator delete删除堆上对象,或者移动栈指针清楚栈上的临时变量
                      COM中调用COM库中的API函数删除
当你创建一个COM对象时,你要跟COM库的API函数说你需要哪个接口,如果对象创建成功,会返回指向那个接口的指针。
然后你就可以调用这个接口中的方法了。




从代码中看看怎么创建一个COM对象
COM库API

HRESULT CoCreateInstance (
    REFCLSID  rclsid,// coclass 的CLSID
    LPUNKNOWN pUnkOuter,// 用于聚合
    DWORD     dwClsContext,//COM server 的类型
    REFIID    riid, // 你请求的接口IID
    LPVOID*   ppv  // 请求的接口返回值);

  你可能会问,如果所有的COM库API的返回值都是HRESULT的话,那么有时候我要返回一些结果怎么办?COM中有个属性是OUT的参数来存放该返回结果,这里就是ppv。


当你调用上述的函数的时候,该函数会在注册表中搜索与CLSID相符合的ID,并且获取该COM服务所在的文件夹,把它放到内存中去,并且创建一个coclass的实力。

HRESULT     hr;
IShellLink* pISL;

hr = CoCreateInstance ( CLSID_ShellLink,         // CLSID of coclass
                        NULL,                    // not used - aggregation
                        CLSCTX_INPROC_SERVER,    // type of server
                        IID_IShellLink,          // IID of interface
                        (void**) &pISL );        // Pointer to our interface pointer

    if ( SUCCEEDED ( hr ) )
        {
        // Call methods using pISL here.
        }
    else
        {
        // Couldn't create the COM object.  hr holds the error code.
        }

删除一个COM对象:
我们不必释放掉一个COM对象,只要说我不用它就行了。每个COM对象都实现了IUnknown接口(因为所有的接口类都从这个接口继承),这个接口中有个release()方法。当你调用了这个方法,你就不能再用这个接口指针了









IUnknown接口类

不是不知道接口类,而是如果你有个一个IUnknown接口指针指向COM对象,你不需要知道这个对象是个啥,这就是向上类型转换的结果,IUnknown是所有类的父类,所有的类都可以向上转型为IUnknown类,这样的好处是所有的函数都可以接受IUnkonwn指针或者引用。
只有三个方法,非常重要
1. AddRef()--告诉COM对象增加自己的引用计数。如果你copy了一个接口指针,比如通过赋值操作,就的把引用计数加一。
2. Release()--减小引用计数。
3. QueryInterface()--请求一个COM对象的接口。

当你用CoCreateInstance()创建了一个COM对象之后,你将会得到一个接口指针。如果这个COM对象有多个接口,即从多个接口继承的话,你就要用QueryInterface()来获得这个接口的指针。

HRESULT IUnknown::QueryInterface (  REFIID iid,   void** ppv );
iid就是你要请求的接口ID
ppv就是你要请求的接口的指


一个简单的例子:
利用shell中的Active Desktop coclass获得当前壁纸的名字。
步骤:
1. 初始化COM库,因为我们要用到其中的函数
2. Create COM对象,获得一个IActiveDesktop借口
3. 调用GetWallpaper方法
4. 如果成功打印名字
5. Release()接口
6. 卸载COM库。
WCHAR   wszWallpaper [MAX_PATH];
CString strPath;
HRESULT hr;
IActiveDesktop
* pIAD;

    
// 1. Initialize the COM library (make Windows load the DLLs). Normally you would
    
// call this in your InitInstance() or other startup code.  In MFC apps, use
    
//  AfxOleInit() instead.</FONT>
    CoInitialize ( NULL );

    
<FONT COLOR="#009900">// 2. Create a COM object, using the Active Desktop coclass provided by the shell.
    
// The 4th parameter tells COM what interface we want (IActiveDesktop).</FONT>
    hr = CoCreateInstance ( CLSID_ActiveDesktop,
                            NULL,
                            CLSCTX_INPROC_SERVER,
                            IID_IActiveDesktop,
                            (
void**&pIAD );

    
if ( SUCCEEDED(hr) )
        {
        
<FONT COLOR="#009900">// 3. If the COM object was created, call its GetWallpaper() method.</FONT>
        hr = pIAD->GetWallpaper ( wszWallpaper, MAX_PATH, 0 );

        
if ( SUCCEEDED(hr) )
            {
            
// 4. If GetWallpaper() succeeded, print the filename it returned.
            
// Note that I'm using wcout to display the Unicode string wszWallpaper.
            
// wcout is the Unicode equivalent of cout.
            wcout << L"Wallpaper path is:\n    " << wszWallpaper << endl << endl;
            }
        
else
            {
            cout 
<< _T("GetWallpaper() failed."<< endl << endl;
            }

        
// 5. Release the interface.
        pIAD->Release();
        }
    
else
        {
        cout 
<< _T("CoCreateInstance() failed."<< endl << endl;
        }

    
// 6. Uninit the COM library.  In MFC apps, this is not necessary since MFC does
    
// it for us.
    CoUninitialize();





1





1
posted @ 2012-04-18 17:17 Dino-Tech 阅读(296) | 评论 (0)编辑 收藏
     摘要: 摘抄一些static的用法  阅读全文
posted @ 2012-04-09 14:09 Dino-Tech 阅读(201) | 评论 (0)编辑 收藏
     摘要: 1. 创建一个对话框资源,就是你要弹出来让别人看的东西。
2. 从CDialogImpl类派生一个新类,处理一些自己想处理的消息,添加一个空间。
3. 添加一个共有成员变量IDD,其实是enum{IDD=IDD_DIALGO};  阅读全文
posted @ 2012-03-22 19:54 Dino-Tech 阅读(406) | 评论 (0)编辑 收藏
     摘要: 网上看的,对自己有用。Cannot convert wtl::cstring to lpstr的解决方法  阅读全文
posted @ 2012-03-22 14:46 Dino-Tech 阅读(437) | 评论 (0)编辑 收藏
     摘要: WTL 状态栏状态添加  阅读全文
posted @ 2012-03-21 10:17 Dino-Tech 阅读(517) | 评论 (0)编辑 收藏
仅列出标题
共6页: 1 2 3 4 5 6