继续同一个问题(共400分):如何实现不同发布者类的继承

yesry 2003-08-25 11:48:02
http://expert.csdn.net/Expert/TopicView1.asp?id=1956642
或http://expert.csdn.net/Expert/topic/1956/1956642.xml?temp=3.515261E-02

现在A公司发布
class A_a
{
public:
AnsiString Name;
ChangeName(AnsiString theName)
{
//具体实现都是Dll或exe二进制形式,但可以肯定成员Name已经改变了
}
};

B公司要使用A公司的代码,并且ChangeName()调用后还要做其他的事情,当然也引用了Name。
class B_a:public A_a
{
public:
ChangeName(AnsiString theName)
{
A_a::ChangeName("我的名字");
ShowMessage(Name);
}
};


高手们,如何实现?很多人说用COM,但是成员Name都各自私有,如果都编写GetName()之类的方法不是很现实,因为有时候传递的是地址或返回new得到的地址等等。
...全文
29 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
yesry 2003-10-30
  • 打赏
  • 举报
回复
可是,如果A来自于一个复杂的父系类,并且如果出现了模板(一般是公开源代码的啊),那么A的.h文件就给了B公司很多信息,我不愿意如此。
ljianq 2003-10-30
  • 打赏
  • 举报
回复
将A设计在DLL中,然后导出整个Class,然后只提供h文件、DLL和LIB文件,B公司的程序员使用h文件同样可以使用A的类,继承也可以,不过需静态连接。
fatwave 2003-10-29
  • 打赏
  • 举报
回复
我已发了一份给你!请查看!
yesry 2003-10-24
  • 打赏
  • 举报
回复
半生不熟的解决了一部分问题。
有没有更好的方案?
Tiejun_Chenfang 2003-08-28
  • 打赏
  • 举报
回复
你真的要噎死我了

//A公司的dll头,unit.h

class __declspec(dllexport) A
{
public:
AnsiString Name;
AnsiString j;
A();
virtual __fastcall void ChangeName(AnsiString theName);
};
extern "C" __declspec(dllexport) A * WINAPI CreateA();
//---------------------------------------------------------------------------


//A公司的dll,unit.cpp

#include "unit1.h"

A::A()
{Name="None";}
void __fastcall A::ChangeName(AnsiString theName)
{ Name=theName;
ShowMessage(Name+"(in dll)"); }

A * WINAPI CreateA()
{ return new A; }


//A公司提供编译好的dll和unit1.h文件,还有lib 文件(静态连接用)

//b公司的代码

//1。在工程中加入dll的lib文件
#include "unit1.h" //2。在代码中加入dll的h文件

class B:public A //B公司的代码
{
public:
AnsiString Name;
AnsiString i;
B()
{
}
virtual __fastcall void ChangeName(AnsiString theName)
{
A::ChangeName(theName);//你可以调用DLL中的实现吗?,当然可以
ShowMessage(Name+"B::f1 in exe");//可以看到A公司修改Name的后果吗?,
//当然可以,是b中的name;
ShowMessage(A::Name+"A::name ");//可以看到A公司修改Name的后果吗?,
//当然可以,是a中的name;

}
void f2()
{
ShowMessage("f1 in B");
}
};
//---------------------------------------------------------------------------
void __fastcall TForm2::Button2Click(TObject *Sender)
{
ShowMessage("BB");
B *b;
b=new B;
b->ChangeName("我叫yesry");//此处弹出3个筐子
delete b;

ShowMessage("AA");
A *a;
a=new A;
a->ChangeName("我叫yesry");//此处弹出1个筐子

delete a;
}

Tiejun_Chenfang 2003-08-28
  • 打赏
  • 举报
回复
B公司还要使用C公司的DLL就不容易了

c公司的子对象都由自己或者由a公司的exe new出来,

然后由a公司的exe将该对象的指针以 A * 的形式给b公司的dll,b公司的dll就可以使用c公司的子对象(以class A的标准形式,执行 class AC 的实际代码)

反之依然
W32API 2003-08-28
  • 打赏
  • 举报
回复
切,你们真是怪事?他既然不提供,你又何必非要去用?那可是侵权行径。
他如要提供,那么他的 CLASS 就应该有足够的方法给你使用,那你又何须如此麻烦?。。。
他如不提供。。。你便要盗版。。。唉
Tiejun_Chenfang 2003-08-28
  • 打赏
  • 举报
回复
你是A公司,怪不得,
把Exe的功能分离到DLL中,让B公司拿去,A公司的Exe间接地调用了基类的功能

实际上就是你做了一个标准接口,让别的公司做附加实现,exe再用标准接口使用啊
yesry 2003-08-28
  • 打赏
  • 举报
回复
不过B公司还要使用C公司的DLL就不容易了,因为B公司只有A公司的声明,对C公司一无所知,他们通过相同的接口模型进行互相调用。
yesry 2003-08-28
  • 打赏
  • 举报
回复
Tiejun_Chenfang的方法已经解决的大部分的事情,我可以把Exe的功能分离到DLL中,让B公司拿去,这样,A公司的Exe间接地调用了基类的功能。
yesry 2003-08-28
  • 打赏
  • 举报
回复
A公司的exe又要用B公司的dll。
B公司对A公司的exe除了声明以外没有源代码,也不能修改。本质就是二次开发,就像IE的插件,但是插件本身使用了IE的很多功能,并且是面向对象的。

Tiejun_Chenfang 2003-08-28
  • 打赏
  • 举报
回复
可不可以这样理解:
A公司有exe,其中有class A的定义实现,和对A的使用
B公司得到了A公司的exe 和A公司class A的声明;
B公司做了自己的DLL,其中有class A的子类的声明及实现。//问题1
A公司的exe又要用B公司的dll。 //问题2

我是这样想的:
B公司对A公司的exe究竟有没有修改源码的权限,
如果有 ,就让A公司导出class A ,B公司的dll就好做了,后面就更简单了
如果没有,你怎么让A公司的Exe使用B

你的问题在不停的变化,我都不知道你究竟是要解决什么问题了
yesry 2003-08-28
  • 打赏
  • 举报
回复
我说得不清楚。
A公司发布了上述class A的说明。B公司(当然好有C公司,D公司,E公司等等)拿到后开发了B,放在一个DLL中(和上述的Exe,DLL情形相反〕,即外挂形式扩充,A公司的Exe像使用class A一样使用B,但是B使用了class A的基础功能后扩展了其中的功能。
不知道我说明白了没有。
Tiejun_Chenfang 2003-08-28
  • 打赏
  • 举报
回复
基类A如果在Exe中实现的,即没有A.LIB可以包含,那该怎么办?


直接用呗

class A{
///
};
class B:public A
{
////
};

A *b;
b=new B;
b->ChangeName("我叫yesry");
delete b;






yesry 2003-08-28
  • 打赏
  • 举报
回复
to Tiejun_Chenfang()
感谢!
基类A如果在Exe中实现的,即没有A.LIB可以包含,那该怎么办?
勉励前行 2003-08-28
  • 打赏
  • 举报
回复
干嘛非要從人家那裡繼承呢,繼承得多,偶合就多,程序就難寫了
我就說說而已, 其實我不會。
TR@SOE 2003-08-28
  • 打赏
  • 举报
回复
说了半天,不知道帖主想干什么。。。。。是不是我水平又退步了????
Tiejun_Chenfang 2003-08-28
  • 打赏
  • 举报
回复
对你的代码的分析及一些疑惑,我用{{{ }}}括起来了。

甲开发了
class MyClass
{
public:
virtual void F1()
{
ShowMessage("MyClass F1 in dll");
}
int x,y;
};

class MyClass2:public MyClass
{
public:
virtual void F1()
{
MyClass::F1();
ShowMessage("MyClass2 F1 in dll");
}
};

extern "C"
__declspec(dllexport) MyClass * WINAPI CreateMyClass()
{
return new MyClass2;
{{{注意:你在这里所用的是MyClass2的new 方法,返回的对象必然是MyClass2}}}
}


发布的时候
class MyClass
{
public:
virtual void F1()
{
//实现的源代码不会发布的。
}
int x,y;
};


对于乙。
//从甲处得到
class MyClass
{
public:
virtual void F1()
{
//实现的源代码不会发布的。
}
int x,y;
};

class MyB:public MyClass
{
virtual void F1()
{
MyClass::F1();//重要问题:如何调用没有源代码的甲的实现方法?如果可以,还能实现MyClass2::F1的功能。
{{{MyClass没有用__declspec(dllexport)导出,你当然无法使用它的实现方法,}}}
{{{对于MyClass2::F1的使用,假如有基类A,子类B和子类C,你想通基类的接口在子类B中用子类C的方法,不要说在dll中,同在一个exe中你做得到吗 }}}}
x=1;y2=3;//两边都能访问。
}
};
MyClass * (*CreateMyClass)();
void __fastcall TForm1::Button1Click(TObject *Sender)
{
HMODULE h;
h=LoadLibrary("Class.dll");
(void*)CreateMyClass=GetProcAddress(h,"CreateMyClass");
MyClass *c=CreateMyClass();//到了这里,我不能实现了,我的原意是实现MyB的实例创建的。
{{{{此处的对象绝对是MyClass2}}}
c->F1();
}


对于 dll中创建MyClass的后裔(在Exe声明和实现),在dll所创建的MyClass的后裔还在exe中使用。这句话可不可以这样理解:

dll中有一个基类,或者又有一个子类,并且已经用dll的形式封装好了,只提供基类的类声明,没有实现代码,现在你想再不同的exe中分别定义基类基础上的子类,并且都用MyClass *c=CreateMyClass()的形式得到自己实际上的子类对象,

1。如果是这样的,你为什么不直接这样(由exe直接生成B)
A *b;
b=new B;
b->ChangeName("我叫yesry");
delete b; //由于你没有将A的析购函数定义为虚函数,所以此处的delete不彻底,但将A的析购函数定义为 虚函数,就无此问题了

2。如果你非要用MyClass *c=CreateMyClass()的形式(dll中创建MyClass的后裔,而该后裔在Exe声明和实现),
可以将CreateMyClass()加一个函数指针型的参数,这个函数由exe提供,它的作用是new 出exe里的子类(因为子类在exe中实现,所以只有exe中的代码才知道子类究竟该怎么new,dll中不知道该类的信息),然后CreateMyClass调用这个函数,这种方案比上面麻烦多了,

我觉得有一个原则,哪里定义类,那里才知道该类的new该怎么实现,





yesry 2003-08-27
  • 打赏
  • 举报
回复
我的天啊!
潘爱民的com本质论我不是没有看过,能解决问题吗?说来说去都是接口,现在是成员变量,还没涉及到static的成员呢。
yesry 2003-08-26
  • 打赏
  • 举报
回复
//DLL,A公司的产品********************************************
#include <vcl.h>
#include <windows.h>
#pragma hdrstop

#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
//---------------------------------------------------------------------------
class A
{
public:
AnsiString Name;
AnsiString j;
A(){Name="None";}
virtual __fastcall void ChangeName(AnsiString theName)
{
Name=theName;
ShowMessage(Name+"(in dll)");
}
};
extern "C"
__declspec(dllexport)
A * WINAPI CreateA()
{
return new A;
}





//Eex********************************************************************
class A//A公司公布的内容
{
public:
AnsiString Name;
AnsiString j;
A(){
//我不告诉你,你如何调用DLL中的实现方法呢?
}
virtual __fastcall void ChangeName(AnsiString theName)
{
//我不告诉你,你如何调用DLL中的实现方法呢?
}
};
class B:public A//B公司的代码
{
public:
AnsiString Name;
AnsiString i;
B()
{
}
virtual __fastcall void ChangeName(AnsiString theName)
{
A::ChangeName(theName);//你可以调用DLL中的实现吗?
ShowMessage(Name+"B::f1 in exe");//可以看到A公司修改Name的后果吗?
}
void f2()
{
ShowMessage("f1 in B");
}
};
void __fastcall TForm1::Button1Click(TObject *Sender)
{
B *b;
b=new B;
b->ChangeName("我叫yesry");
delete b;
}
//---------------------------------------------------------------------------
加载更多回复(3)
本课程为Django第七季课程:用户登陆模块     本季课程主要实现图片的上传和展示,用户登陆账号的管理,用户账号的登陆、个人信息的修改、注销,使用邮箱地址找回密码。包含的主要知识点有:virtualenv虚拟环境、pip下载包、多app项目开发、templates模板的继承、font-awesome图标的使用、原生SQL语句和数据库交互、ORM模型和数据库交互、LayUI页面布局、jQuery实现用户交互、Ajax的异步请求、页面的块状展示数据、表格展示数据、表格的页、数据的增改删改、Layer弹出层使用、表单的验证、照片的上传、照片的展示、图片展示的页、照片的标准和放大、用户账号的增删改查、用户的登陆、Session和Cookie、Redis服务器的部署和基本配置、Django发送邮件等等知识点      本案例完整的演示了项目实现过程,虽然不复杂,但涉及的内容非常多,特别是前后端交互的时候,有诸多的坑等着你去踩,好在王老师全程代码呈现,带着大家一起填坑,大大提高学习效率的同时,也培养了大家良好的代码习惯,希望大家一致跟着王老师学习Python开发。 Django第八季课程课程预告:权限管理Django第九季课程课程预告:Web项目发布到阿里云 课程目标:本系列课程是从零基础开始并深入讲解Django,最终学会使用Django框架开发企业级的项目。课程知识点详细,项目实战贴近企业需求。本系列课程除了非常详细的讲解Django框架本身的知识点以外,还讲解了web开发中所需要用到的技术,学完本系列课程后,您将独立做出一个具有后台管理系统,并且前端非常优美实用的网站。对于从事一份Python Web开发相关的工作简直轻而易举。 

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧