如何实现:A类中创建并使用了B类的对象,现在写一个C类继承B类,同时A类也被修改为创建C类

深林孤鹰 2020-01-17 08:31:31
假设写个模型:
class B
{

};

class A
{
public:
B* pB;
void init()
{
pB = new B;
}
};

现在想扩展B类的,但是不修改A类,使A类init函数创建C类的对象,如何能实现呢?
class C:public B
{
void extend(){...}
}

现在能想到的解决方案有2个:模板类(得公开源代码)和回调函数(将init修改为回调,太麻烦),不知有没有什么奇淫技巧来实现呢~谢谢
...全文
795 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
Linkkk丶 2020-01-18
  • 打赏
  • 举报
回复
外部实例化B或者C, 指针传入init,虚函数各自调用对象的成员函数
深林孤鹰 2020-01-17
  • 打赏
  • 举报
回复
是的,B函数只是框架最基础的功能,然后客户可以扩展一些数据,甚至可以写逻辑。
感谢大家的回答~
真相重于对错 2020-01-17
  • 打赏
  • 举报
回复
既然C继承于B 完全可以 void init() { pB = new C; }
寻开心 2020-01-17
  • 打赏
  • 举报
回复
所以
A是如何实现的,以及对pB这个数据对象的约束,是能否扩展的关键

如果pB是可以在A的对象初始化或者其他阶段通过传参进入的,那么你的扩展非常容易
大不了把B的一些方法虚化(virtual),甚至B本身都可以是个纯虚类,实际使用的时候用B的派生类, A调用B的这些方法就没有顾忌了

那些标准的模板是怎么样的,包括你说的回调函数, 其实都把数据做活了, 让B类的方法和数据不由A控制死
弓人水 2020-01-17
  • 打赏
  • 举报
回复
模板类应该能满足吧,A和B类不需要要公开源代码,派生类按照各自需求实现即可。
class A
{
public:
B* pB;

template<class T>
void init()
{
pB = new T;
}
};
...
A a;
a.init<B>();
a.init<C>();
深林孤鹰 2020-01-17
  • 打赏
  • 举报
回复
禁止类的继承比较简单 直接用类厂造就行,把各种构造函数都做成private。
真相重于对错 2020-01-17
  • 打赏
  • 举报
回复
既然A不让改,那么封装A 参考一下proxy模式
深林孤鹰 2020-01-17
  • 打赏
  • 举报
回复
我最初的构想就是做个框架,框架实现了一些通用的功能,还可以在不修改源码的情况下再次扩展功能。c++语言想要跳出原来代码去执行扩展代码再返回,也想来想去也就是回调函数、派生类和模板类了,但模板类必须开源整个类,还不如直接修改源码;回调函数方便,效率高,但可读性差也容易出错。刚才想到的那个办法比较优雅,其实是用到了c++的动态性特性,创建对象时用一个类厂对象去创建,扩展功能后重新继承派生那个类厂,这样就动态的去创建了B的派生对象C。而C对象由于继承自类B,所以完全不影响A的内部运行。
举个例子,一个列表实现就可以用这个方法,list类管理多个node对象,用户可以将自己的数据保存在node类的派生类中。
寻开心 2020-01-17
  • 打赏
  • 举报
回复
即便A里面的pB是pulic的, 但是能随意把它delete掉,或者用新的函数替代init函数来完成b的创建吗
这个还是取决于A已有的实现方式
如果A在构造的时候,就内部调用了init完成了pB的初始化,并做了其他的一些关联性操作,你就没法替换他
你可以继承A,再弄一套数据管理出来, 但是那还是A吗? 某种意义上是复制了一套新的出来。
A是你自己的代码或者开源的,是可以改造;
如果来自他人的系统,没有源码级的改造,只能在继承类上想办法
能否实现,还是取决于A的具体实现方式, A是完全能堵死这些可能性的。
有些商业软件就是这样, 它的对象禁止再继承,禁止再修改内部数据类型。
寻开心 2020-01-17
  • 打赏
  • 举报
回复
不改A没有办法吧
A里面的Init函数,没有传参, pB = new B; 这个写死了。
无论如何都是B对象了,没有办法把它改成C对象
深林孤鹰 2020-01-17
  • 打赏
  • 举报
回复
引用 5 楼 弓人水 的回复:
既然,A类不能修改,且内部管理B类,那么无法让A去管理扩展的C了,因为既然new的是B类,就不可能动态让B变成C类了。


其实如果不用类模板,就得想办法在创建B类对象时跳转到其他地方下功夫。回调函数是个好办法,不过受你的启发用模板类、类厂和重载函数来优雅的实现了这个办法(其实核心仍然是跳转,只是代码比回调函数好看些)。大体实现如下:
创建一个类厂F,成员函数ceate来创建B类对象;
把F类的指针f定义在A中,把A类所有创建B类对象,都改为为f.create();
写C类派生A类,然后用另一个类厂FF派生F类,重写create,内容是创建C类对象;
将FF的对象赋值给A对象的f指针。
虽然比较麻烦,但是用起来还是挺方便的~
甚至可以把F和FF写到A类内,FF做成模板类会更方便,哈哈~
  • 打赏
  • 举报
回复
既然
public:
B* pB;
从外部直接创建个C实例然后设置pB即可
弓人水 2020-01-17
  • 打赏
  • 举报
回复
既然,A类不能修改,且内部管理B类,那么无法让A去管理扩展的C了,因为既然new的是B类,就不可能动态让B变成C类了。
深林孤鹰 2020-01-17
  • 打赏
  • 举报
回复
引用 2 楼 真相重于对错 的回复:
既然C继承于B
完全可以
void init()
{
pB = new C;
}

不行啊,前提是不能更改A类代码(init函数等)。
深林孤鹰 2020-01-17
  • 打赏
  • 举报
回复
引用 1 楼 弓人水 的回复:
模板类应该能满足吧,A和B类不需要要公开源代码,派生类按照各自需求实现即可。
class A
{
public:
B* pB;

template<class T>
void init()
{
pB = new T;
}
};
...
A a;
a.init<B>();
a.init<C>();

谢谢!不过我的例子可能不恰当,因为A类没有类似init函数去创建B类,A是内部自己管理B类的创建和释放的,所以没办法把模板参数传递进去...
用模板类的话只能把整个A类都作为模板,不过这样得把所有代码暴露出来。

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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