手上有个应用系统,其中使用了一个静态库,这个静态库当中用到了一个类如CClassA,现在由于系统运行环境变化,需要调用新的CClassA才能正常运行,我现在需要的是,如何可以让这个应用系统在不同环境下使用不同的CClassA
举例,我写了个静态库,其中用到CClassA,本来在WIN2000使用下CClassA正常; 但是如果要保证静态库继续可用,在WIN XP下我必须用个新的CClassA,为了保证静态库中代码不变化,我把2个CClassA中的方法接口参数保持完全一致,类名也保持CClassA,我现在手上旧的CClassA的CPP和H文件,新的CClassA的CPP和H文件
用什么方法,让我这静态库能在不同系统环境下用不同的CClassA

解决方案 »

  1.   

    同事有提说可以用宏,但我在VC6中都不知道编译的时候把哪个CClassA的CPP放进工程,都不放,直接没LINK
    我在想光靠宏能把新旧CLASSA的实现都编译进静态库??
    现在想把CClassA搞成动态库
      

  2.   

    把两个版本的类用不同的名称,程序中动态构造对象。 由于为了保证其他有调用CClassA的上层类代码不变化,最好保持类名不变,
    而且CClassA的头文件超过1W行,改很累的
      

  3.   

    再建一个工程,同样的代码,生成两份相同名字的lib
    安装包里带上两份lib,可以放不同的目录,
    安装的时候根据os类型,deploy对应目录里面的lib
      

  4.   

    可以从这两个类中抽象出一个公共的类,把这个公共的类叫做CClassA。这样既保持了接口的不变,又保证了能动态创建不同的具体类。
      

  5.   

    楼主看看下面这个类这样的实现可行不?
    // MyClass.h: interface for the CMyClass class.
    //
    //////////////////////////////////////////////////////////////////////#if !defined(AFX_MYCLASS_H__3F52F5FE_3A19_4117_A1A6_EDCA84B6FCDD__INCLUDED_)
    #define AFX_MYCLASS_H__3F52F5FE_3A19_4117_A1A6_EDCA84B6FCDD__INCLUDED_#if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000#define WIN2000class CMyClass  
    {
    public:
    void Show();
    CMyClass();
    virtual ~CMyClass();};#endif // !defined(AFX_MYCLASS_H__3F52F5FE_3A19_4117_A1A6_EDCA84B6FCDD__INCLUDED_)// MyClass.cpp: implementation of the CMyClass class.
    //
    //////////////////////////////////////////////////////////////////////#include "stdafx.h"
    #include "FormSDI.h"
    #include "MyClass.h"#ifdef _DEBUG
    #undef THIS_FILE
    static char THIS_FILE[]=__FILE__;
    #define new DEBUG_NEW
    #endif//////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////CMyClass::CMyClass()
    {}CMyClass::~CMyClass()
    {}#ifdef WIN2000   //通过宏定义来告诉编译器连接那个函数实现void CMyClass::Show()
    {
    AfxMessageBox("Windows 2000");
    }#endif#ifdef WINXPvoid CMyClass::Show()
    {
    AfxMessageBox("Windows XP");
    }#endif
      

  6.   

    不知道以前的程序使用CClassA的方法是不是全是引用和指针,要是这样,将CClassA作为基类派生出两个类,其中一个是原来库类的派生类,在程序中根据条件将不同的派生类付直那些CClassA的引用和指针
      

  7.   

    按楼主的意思,好像是要动态创建啊,静态方法,例如宏之类的是不行的最简单的用个类厂模式就行定义一个抽象基类,把class a的基本功能全部抽象出来  class base
    {
    public:
      virtual int func1() = 0;
      virtual int func2() = 0;protected:
       int _num1;
    };a2k和axp分别实现不同系统的功能class a2k : public base    // windows 2000功能
    {
    public:
      int func1() ;
      int func2(); 
    }class axp : public base   // windows xp功能
    {
    public:
      int func1() ;
      int func2(); 
    }实现类厂方法,根据操作系统返回不同的程序对象base * create(int os_type)
    {
      switch(os_type)
      {
       case 0:     // 2k
         return new a2k;
       case 1:
         return new axp;
       default:
         return NULL;
      }
    }程序其它地方,直接根据create函数返回的对象指针操作就行了base *p = create(0);
    p->func1();
      

  8.   

    可以参考不同版本的系统调用不同版本的API
      

  9.   


    后来想法是,按原来的MyClass,为了把类名分开,重新再封装一层MySubClass(原来的MyClass.lib想当于新的MySubClassA.lib,但类名不同),再在MyClass中使用不同的MySubClass,上面大哥是这意思么,-_-我画了个类图,怎么插进来啊,图片在本地
      

  10.   

    Tinary3v0#ifdef WIN2000   //通过宏定义来告诉编译器连接那个函数实现#ifdef WINXPMarkZ 说的“用宏只能在编译期改变代码,对最终可执行程序来说只有一个类起作用”,我也同意,觉得不行
    ilovedrv 提到类工厂,昨天刚发完帖后和同事讨论,同事一听也是先想到类工厂,不过我没对这没什么概念,上网看了一会,后来他建议我用我上面回复的方法,不知道是不是这意思
      

  11.   


    这是典型的类厂,是解决这类问题的好办法,把我上面写的create作为MyClass成员函数, 所有的操作都通过MyClass调用基类指针实现
    class MyClass
    {
    public:
       MyClass(int os_type) { _b = create(os_type);}   int func1() { return _b->func1(); }    // 功能1实现
    private:   base *create(int os_type);   // 看13楼create实现private:
       base *_b;     // 根据操作系统的不同,创建的对象
    }
      

  12.   

    我提的方法是从lib库文件上来解决,如果你想从代码上,就可以再封装一层,动态决定用哪个Class
      

  13.   

    折腾了几天,最后还是有问题,虽然能编译通过,但由于最底层调用到2个同名类,结果在执行的时候不能正常进入正确的类,和SETTING中LIB的顺序有关,由于最近有紧急任务只好先暂停,该有了最直接的办法,把类名改了
    我把逻辑再发下,望有高人指点,让公司一个前辈看了改了最后也还有问题EXE 
    ------调用
    MyClass.lib  
    -----------
    MyClass.hclass MyClass
    {
       ....
    private:
       CMyBaseSubClass *m_pBase;
       ....
    }MyClass.cpp#include "MySubClassA.h"
    #include "MySubClassB.h"MyClass :: MyClass()
    {
       ....
       if(os)
         m_pBase = new CMySubClassA ();
       else
         m_pBase = new CMySubClassB ();
       ....
    }MyClass :: fun()
    {
       m_pBase->fun();
    }-------------------
    MyBaseSubClass.hclass CMyBaseSubClass
    {
       ....
       virtual fun() = 0;
       ....
    }-------------------
    派生类 CMySubClassA
    MySubClassA.hclass CMySubClassA : public CMyBaseSubClass
    {
       ....
       fun();
       ....
    }---------------------
    MySubClassA.cpp#include "ClassA.h" //旧的CClassA/*
    //ver 1
    CClassA A;   //后来多是对这里调用CClassA的改动,开始是用全局变量,2个版本合用后,LINK报错重名CMySubClassA :: fun
    {
      A.fun()
    }
    *//*
    //ver 2
    还是在MySubClassA.cpp
    class CGlobalVarA  //MySubClassB中的类名不同
    {
    private:
     static CClassA A; 
    }
    static CClassA A = NULL ; 
    CMySubClassA :: fun
    {
      CGlobalVarA::A.fun();
    }
    //有点忘了是不是这样写的刚出差,失败代码没带出来,前辈提议说将全局变量改为某个新类的静态成员变量
    //我个人认为是为了避免LINK重名
    */
    编译的时候,先生成MySubClassA.lib 和 MySubClassB.lib ,最后EXE LINK的时候将MyClass.lib, MySubClassA.lib 和 MySubClassB.lib都包含
      

  14.   

    用编译宏的方法:
    # if difine win2000
    不可以吗?