C++中的property库的设计与实现过程(四)——消除讨厌的warning C4355

本文介绍了在C++编程中遇到的warning C4355,即在基类初始化列表中使用'this'导致的警告。作者探讨了解决方案,通过成员变量指针的概念,利用偏移量计算父类指针地址,尽管这种方法涉及了一些复杂的表达式。此外,由于警告无法完全消除,作者选择了使用pragma warning来在特定区域禁用该警告,以确保用户在使用库时不会受到影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接下来应该是给property_bag写大量的操作符重载了……唔,稍微等等,怎么总是有一个warning消不掉呢?就是下面这个(使用VS 2005):
warning C4355: 'this' : used in base member initializer list
这个C4355是没有办法简单消除的,除非不用this,但又不可能,因为我property_bag的构造函数需要用到父类的指针。那么,能够做改变的就是我的构造函数了。

在这里,我联想到成员变量指针的概念:它仅仅是一个偏移量而已。那么我是否可以用这个偏移量和变量自己的指针反过来算出父类的指针地址呢?答案是肯定的,但是需要用到比较丑陋的trick。
具体代码如下:
namespace  rdxLib  {
    template 
<typename Parent, typename Type>
    
class property_bag : public detail::basic_type_impl<Type, detail::is_derivable<Type>::value>
    
{
        typedef property_bag
<Parent, Type> MyType;
        
typedef  MyType (Parent::*MyOffset);
         typedef  typename ::boost::call_traits<Type>::param_type       param_type;
         typedef  typename ::boost::call_traits<Type>::reference        reference;
         typedef  typename ::boost::call_traits<Type>::const_reference  const_reference;

         typedef param_type (Parent::*Get)()  const;
         typedef void (Parent::*Set)(param_type);

        Parent * parent_;
        Get getFunction_;
        Set setFunction_;

     public:
        property_bag(MyOffset offset, Get get, Set set)
            : parent_( reinterpret_cast<Parent*>((intptr_t)this - (ptrdiff_t)(&(((Parent*)0)->*offset))))
            , getFunction_(get)
            , setFunction_(set)
        {
        }

     private:
        property_bag()
        {
        }
    };
}

关键的代码用黄色标亮,主要由两部分。首先是定义偏移量的类型,也就是那个MyOffset类型,接下来是那个暴复杂的表达式。
简单说说表达式:&(((Parent*)0)->*offset)这个表达式算出了变量在父类中的偏移量具体数值,而ptrdiff_t则是C++标准中规定的指针偏移量类型,强制转换一下可以避免warning,接着是this,转成intptr_t类型之后就可以做加减法了,最后是这两个值相减(注意,是相减,因为父类的this地址在成员的this之前)并强制转换成Parent*指针,结果就是父类的指针。

不过很可惜,warning并没有消除,因为property_bag用到了自己的this!不过这就好办多了,我可以手动的禁掉这个warning:
#pragma  warning(push)
#pragma  warning(disable: 4355)

//  ...

#pragma  warning(pop)

这下好了,起码用这个库的用户不再被warning所困扰了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值