首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >常量构造函数

常量构造函数
EN

Stack Overflow用户
提问于 2015-05-13 17:00:48
回答 1查看 202关注 0票数 3

是否有可能在C++中实现只允许创建const对象的构造函数?

我正在考虑用const和非const方法为接口创建一个装饰器类。从const基对象初始化装饰器应该只能产生常量装饰器,但是从非常量初始化应该产生全功能的装饰器。

代码语言:javascript
复制
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
}

怎样才能达到类似的效果呢?

EN

回答 1

Stack Overflow用户

发布于 2015-05-13 17:52:57

我只能通过不使用返回const对象的构造函数,而使用返回shared_ptr<const decorator>的静态函数(a-la命名构造函数)来实现这一点。这“编码”了类型中的常量,并禁止非常数调用:

代码语言:javascript
复制
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用于非常量装饰器,从而获得常量和非常量的相似使用模式。

请注意,这将要求您删除decorator的复制构造函数和operator=,因为它们将失去不变性。但是,在您的带有假设常量构造函数的版本中也存在类似的问题。

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30210154

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档