【发布时间】:2012-02-25 09:42:14
【问题描述】:
说,代码
class Derived: public Base {....}
Base* b_ptr = new( malloc(sizeof(Derived)) ) Base(1);
b_ptr->f(2);
Derived* d_ptr = new(b_ptr) Derived(3);
b_ptr->g(4);
d_ptr->f(5);
似乎合理,LSP满意。
我怀疑当 Base 和 Derived 是 POD 时,此代码是标准允许的,否则不允许(因为 vtbl ptr 被覆盖)。我的问题的第一部分是:请指出这种覆盖的精确前提。
可能存在其他标准允许的重写方式。
我的问题的第二部分是:还有其他方法吗?它们的确切前提是什么?
更新:我不想写这样的代码;我对这种代码的理论可能性(或不可能)感兴趣。所以,这是“标准的纳粹”问题,而不是“我怎么能……”的问题。 (我的问题要转移到其他 stackoverflow 网站吗?)
UPDATE2&4:析构函数呢?此代码的假定语义是“基本实例(破坏性地)由派生实例的切片更新”。为简单起见,让我们假设 Base 类有一个简单的析构函数。
UPDATE3:对我来说最有趣的是通过b_ptr->g(4)访问的有效性
【问题讨论】:
-
您实际上想要完成什么?在不知情的情况下很难提出替代方案。
-
亲爱的主,这代码太可怕了......
-
行
b_ptr->g(4)是UB,因为在第二个new之后,原始对象*b_ptr不再存在。要获得一个新的基指针,你必须说类似static_cast<Base*>(d_ptr)。 -
是的,你至少应该使用 new 和 delete 运算符,而不是 malloc 和 free 函数。
-
@Serge:他正在使用
new运算符。如果你想说他应该使用void* operator new(size_t)分配函数,那与new运算符完全不同。
标签: c++ memory overwrite language-lawyer