const构造函数

Const constructor

本文关键字:构造函数 const      更新时间:2023-10-16

在C 中是否可以实现仅允许创建const对象的构造函数?

我正在考虑将装饰器类与const和非const方法的接口进行。从const基本对象初始化装饰器只能产生const装饰器,但是从非const初始化应产生功能齐全的装饰器。

struct A
{
    virtual void foo();         // requires non-const A
    virtual void bar() const;   // const method
};
class decorator : public A
{
private:
    std::shared_ptr<A> p_impl;
public:
    virtual void foo()          { p_impl->foo(); }
    virtual void bar() const    { p_impl->bar(); }
    // regular constructor
    decorator(std::shared_ptr<A> const & p)             : p_impl(p) {} 
    // hypothetical constructor that makes a const
    decorator(std::shared_ptr<A const> const & p) const : p_impl(p) {} 
};
void F(std::shared_ptr<A> const       & regular_a
     , std::shared_ptr<A const> const & const_a   )
{
    decorator regular_decorator(regular_a);
    regular_decorator.foo(); // all good
    regular_decorator.bar(); // all good
    decorator bad_decorator(const_a);   // compiler error
    // trying to use a const constructor to init a non-const object
    const decorator const_decorator(const_a); // all good
    const_decorator.foo(); // compiler error, foo is not const
    const_decorator.bar(); // all good
    // I have a lot of these in code that is beyond my control
    decorator bad_practice(const_cast<decorator&>(const_decorator));
    bad_practice.foo(); // all good
}

如何达到类似的效果?

我只能通过没有返回 const对象的构造函数来获得此工作,而是返回 shared_ptr<const decorator>的静态函数(a-la命名构造函数)。这是类型中的"编码"构成,并禁止非传播呼叫:

struct A
{
    virtual void foo();         // requires non-const A
    virtual void bar() const;   // const method
};
class decorator : public A
{
private:
    std::shared_ptr<A> p_impl;
public:
    virtual void foo()          { p_impl->foo(); }
    virtual void bar() const    { p_impl->bar(); }
    // regular constructor
    decorator(std::shared_ptr<A> const & p)             : p_impl(p) {} 
    static std::shared_ptr<decorator const> constDecorator(std::shared_ptr<A const> const & p) { return std::make_shared<decorator>(std::const_pointer_cast<A>(p)); } 
};
void F(std::shared_ptr<A> const       & regular_a
     , std::shared_ptr<A const> const & const_a   )
{
    decorator regular_decorator(regular_a);
    regular_decorator.foo(); // all good
    regular_decorator.bar(); // all good
    decorator bad_decorator(const_a);   // compiler error
    // trying to use a const constructor to init a non-const object
    std::shared_ptr<const decorator> const_decorator = decorator::constDecorator(const_a); // all good
    const_decorator->foo(); // compiler error, foo is not const
    const_decorator->bar(); // all good
    // I have a lot of these in code that is beyond my control
    decorator bad_practice(const_cast<decorator&>(*const_decorator));
    bad_practice.foo(); // all good
}

当然,您也可以通过声明另一个静态功能来将shared_ptr用于非CONST装饰器,从而获得const和non-const的使用模式相似。

请注意,这将需要您为decorator删除复制构造函数和operator=,因为它们会丢失constness。但是,您的版本中存在类似的问题。

我尝试过的另一种方法是使decorator成为模板类,并且具有两种不同类型:decorator<A>decorator<const A>,希望编译器不使用decorator<const A>::foo(),除非使用它,否则它即使不使用,也可以继续实例化。

相关文章: