使用常量和非常量函数 - C++

Nav*_*K N 3 c++ const

我有3节课.它是最简单的形式,看起来像,

class tree
{
public:
    tree_node* find_node(const std::string& text) {
       return factory.find(text);
    }
private:
    tree_node_factory factory;
}

class tree_node
{
public:
    tree_node(const std::string& text) : text_(text) {}

    const std::string& text() const {
       return text_;
    }

    void set_parent(const tree_node* new_parent);

private:
    std::string text_;
}

class tree_node_factory
{
public:
    tree_node* find(const std::string& text);
private:
    std::vector<tree_node*> allocated_nodes;
}
Run Code Online (Sandbox Code Playgroud)

我不想让用户tree修改tree_node像方法返回的方法find_node.所以我改变了,find_node并且tree_node_factory::find,

const tree_node* find_node(const std::string& text) const {
    return factory.find(text);
}

const tree_node* find(const std::string& text) const;
Run Code Online (Sandbox Code Playgroud)

问题是tree内部应该能够修改节点并处理类似的方法set_parent.但由于工厂只返回const节点,我最终在工厂中添加了另一个重载(非const版本)find.

tree_node* find(const std::string& text);
Run Code Online (Sandbox Code Playgroud)

我想知道这是处理这类问题的正确方法吗?我看到代码在const和非const版本中都是重复的.

有什么想法吗..?

GMa*_*ckG 7

Scott Meyers的书" Effective C++ "中的第3项演示了一种删除此代码重复的方法.基本上,在你的非const函数中,你将添加const this,调用const版本,然后将const转换掉.这很安全; 虽然写一个const变量会导致未定义的行为,因为this它最初是非const的,所以没关系.

例:

const std::string& operator[](size_t index) const
{
    // some other code

    // since `this` isn't really const, this is modifiable 
    return mData[index]; 
}

std::string& operator[](size_t index)
{
    return const_cast<std::string&> // (3) take const off result
            (static_cast<const my_type&> // (1) add const
            (*this)[index]); // (2) use const version

}
Run Code Online (Sandbox Code Playgroud)

通常它都会在一条线上.您也可以为它制作一个实用程序.

请注意一个警告:如果const版本返回"真正的"const对象,则此方法显然会导致未定义的行为.返回值的常量必须通过引用的对象的常量来反映this.这是破码:

const std::string& operator[](size_t index) const
{
    static const std::string constString = "Don't modify me.";

    if (index == 0)
    {
        // even though `this` isn't really const, this is NOT modifiable
        return constString; 
    }

    return mData[index - 1];
}

std::string& operator[](size_t index)
{
    return const_cast<std::string&> // (3) !!! take const off result !!!
            (static_cast<const my_type&> // (1)
            (*this)[index]); // (2)

}
Run Code Online (Sandbox Code Playgroud)

在实践中,我们避免全球状态,所以这很少是一个问题.无论如何,检查是微不足道的.