假设我有两个继承具有纯虚函数的基类的类。这两个类都实现了它自己的那个函数版本,但不添加额外的成员变量,因此它们具有相同的大小。现在有时候,在程序执行过程中,我想将一个类转换为另一个类而不复制其所有数据。所以基本上我想让它使用其他类的虚拟表。有没有一种便携的方式来做到这一点?在运行时动态更改虚拟指针
回答
可移植的方法是实现你自己的类系统,它实际上具有可被复制的虚拟指针。
标准C++中没有这样的虚拟指针。
有没有一种便携的方式来做到这一点?
绝对不是。关于如何实现虚拟功能的具体细节并未由规范定义,因此不存在假装一个虚拟类别是另一种虚拟类别的方式。
没有。就语言而言,不存在虚拟表格之类的东西,更不用说关于它的外观/包含/存储位置的规则。
某种形式的作文可能更适合您的任务。
正如其他答案所说,实际上改变vtable是绝对不可移植的。
不过,也有一些变通办法,可以让你完成类似的语义没有实际改变类类型:
这种简单的解决办法是用描述当前实施的枚举“滚你自己的”遗产:
class MyClass
{
public:
enum DerivedType { A, B };
private:
DerivedType myType;
public:
void myVirtualFunction()
{
if (myType == A)
myAFunction();
else
myBFunction();
}
}
您也可以使用函数指针作为公共成员变量,该变量设置为指示类类型的函数。然后你可以设置功能指针到另一个类的功能来“改变它的类型”
既然你提到你想避免复制数据,你可以保留你的不同的类,但有引用计数指针给你所有的成员变量,以便您可以快速创建彼此相反类型的新对象。
挪威安徒生咨询公司(现埃森哲)的一位年轻同事曾经向我提出过一个严重的问题。他们在Visual Basic中开发的应用程序花了很长时间来加载。他怀疑这可能是因为他们把每个类放在它自己的DLL中?
由于担心最坏情况,我进一步询问。是的,他们也有任何崩溃等问题
他怀疑,否则莫名其妙的崩溃可能会连接到他们的巧妙方案改变对象的类型在运行时,通过替换vtable指针?
我建议也许他们不应该做这些事情。他怀疑地看着我,冒险说他们没有时间再次从零开始做事。事实上,他们已经在扩展它,并且存在各种各样的问题,比如他们的项目负责人坚持他们在客户现场工作,而不是参加强制性会议。对我而言,这听起来像蘑菇管理(让他们在黑暗中,当一个人头弹出来,切开它):这些东西经常一起。
无论如何,我给你的建议是:不要。
或许可以改为实现快速移动操作,从移动数据到b?
或者,您可能会发现,这些都是不成熟的优化?
干杯&心连心,
我同意100%。好像开发已经够难了!当一些承包商决定增加一些额外的数据成员到'他们'的子类时会发生什么?我认为继承等的一个原因就是为了避免这类旅行。 –
即使这个问题是旧的,我想弹出一个办法做到这一点。 (对可移植性不太确定)
从我所了解的你有一个类B
和C
继承自某个类A
并且它们之间只存在一个虚函数。 (如果B
和C
是不相关的,以及我在这里的方法工作。)
class A {
public:
virtual std::string hello() = 0;
};
class B : public A {
public:
virtual std::string hello() { return "B"; }
};
class C : public A {
public:
virtual std::string hello() { return "C"; }
};
然后你想利用B
到C
然后调用hello
,并得到"B"
。
所以,有一种方法来创建boost::any
的淡化版本,只要它符合:)
struct parent {};
template< typename T >
struct child : public parent {
child(T const& t): item(t){}
mutable T item;
};
template< typename T >
T& as(parent const & p) { return static_cast< child<T> const& >(p).item; }
会投什么东西然后一切都混合在一起:
B b;
parent* p = new child<B>(b);
std::cout << as<C>(*p).hello() << std::endl;
// ==== OUTPUT ====
// B
可以看到代码在行动here。
再向前迈进一步,我们可以创建一个从一种类型到另一种转换无需提供有关他们之间发生的事情一个蚊蚋的追尾功能。
template< typename TO, typename FROM >
TO& convert(FROM const& from) {
parent* p = new child<FROM>(from);
return as<TO>(p);
};
这可以运行here。
(意识到我错过了这些示例代码链接的继承,但看完这个问题后,我认为这是实际需要的。所以,看到没有继承测试去here)
一些其他代码,我开始玩,我认为可能会帮助一些以及...
#include <iostream>
#include <string>
class B {
public:
virtual char hello() {return 'B';}
};
class C {
public:
virtual int hello() {return 65;}
};
struct parent {};
template< typename T >
struct child : public parent {
child(T const& t): item(t){}
mutable T item;
};
template< typename T >
T& as(parent const & p) { return static_cast< child<T> const& >(p).item; }
template< typename TO, typename FROM >
TO& convert(FROM const& from) {
parent* p = new child<FROM>(from);
return as<TO>(*p);
};
int main()
{
B b;
std::cout << convert< C, B >(b).hello() << std::endl;
C c;
std::cout << convert< B, C >(c).hello() << std::endl;
}
// ==== OUTPUT ====
// 66
// A
想出如何使这一切的转换函数中:
template< typename TO, typename FROM >
TO& convert(FROM const& from) {
struct parent {};
struct child : public parent {
child(FROM const& t): item(t){}
mutable FROM item;
};
struct sibling : public parent {
sibling(TO const& t): item(t){}
mutable TO item;
};
parent* p = new child(from);
return static_cast< sibling const& >(*p).item;
};
- 1. CakePHP在运行时更改虚拟域
- 2. Noobie虚拟指针混淆
- 3. 虚拟表格指针
- 4. 运行时动态布局更改
- 5. 虚空指针的动态数组
- 6. 虚拟表格指针和虚拟表格模拟
- 7. 将指针的名称更改为自动运行
- 8. 更改指针指针指针引用
- 9. 在运行时更改静态变量
- 10. 虚拟指针的打印值
- 11. 从基指针的C++虚拟类?
- 12. 指针到虚拟成员函数
- 13. 虚拟方法和这个指针
- 14. 虚拟多重继承和指针
- 15. 纯虚拟方法VS.函数指针
- 16. 启动虚拟机,运行exe,在azure自动化中停止虚拟机
- 17. 在运行时动态修改块
- 18. 在跟踪指针时显示虚拟图像
- 19. 在运行时更改滚动窗格的拇指颜色
- 20. Azure虚拟网络网关 - 动态公共IP地址更改
- 21. 是否有可能访问多态类中的虚拟指针
- 22. 同时运行Java虚拟机
- 23. 运行时绑定和虚拟继承
- 24. 在运行时更改动画
- 25. Android - 在运行时更改活动contentview
- 26. 在运行时更改启动页面
- 27. 空指针在opencv(QT)运行时
- 28. 空指针在运行时异常
- 29. 更改虚拟财产
- 30. 虚拟服务器更改
能否请您就如何做到这一点的例子吗? – CODError