从 const 成员函数调用非常量成员函数

发布于 2024-09-30 01:17:45 字数 292 浏览 3 评论 0原文

我想知道是否可以从 const 成员函数调用非常量成员函数。在下面的示例中,首先给出了编译器错误。我明白为什么会出现错误,我想知道是否有办法解决它。

class Foo
{
   const int& First() const
   {
         return Second();
   }

   int& Second()
   {
        return m_bar;
   }

   int m_bar;
}

我真的不想讨论这样做是否明智,我很好奇它是否可能。

I would like to know if its possible to call a non-const member function from a const member function. In the example below First gives a compiler error. I understand why it gives an error, I would like to know if there is a way to work around it.

class Foo
{
   const int& First() const
   {
         return Second();
   }

   int& Second()
   {
        return m_bar;
   }

   int m_bar;
}

I don't really want to discuss the wisdom of doing this, I'm curious if its even possible.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

总以为 2024-10-07 01:17:45
return (const_cast<Foo*>(this))->Second();

然后,静静地哭。

return (const_cast<Foo*>(this))->Second();

Then cry, quietly.

初与友歌 2024-10-07 01:17:45

这是可能

const int& First() const 
{ 
    return const_cast<Foo*>(this)->Second(); 
}

int& Second() { return m_bar; }

我不推荐这样做;它丑陋且危险(任何使用 const_cast 都是危险的)。

最好将尽可能多的常用功能转移到辅助函数中,然后让 const 和非常量成员函数各自执行尽可能少的工作。

对于像这样的简单访问器,从两个函数返回 m_bar; 与从另一个函数调用一个函数一样容易。

It is possible:

const int& First() const 
{ 
    return const_cast<Foo*>(this)->Second(); 
}

int& Second() { return m_bar; }

I wouldn't recommend this; it's ugly and dangerous (any use of const_cast is dangerous).

It's better to move as much common functionality as you can into helper functions, then have your const and non-const member functions each do as little work as they need to.

In the case of a simple accessor like this, it's just as easy to return m_bar; from both of the functions as it is to call one function from the other.

慵挽 2024-10-07 01:17:45

根据const的定义,函数不应该修改对象的状态。但如果它调用另一个非常量成员,则对象的状态可能会改变,因此是不允许的。

我知道你说过你不想听到这个,但我认为这对于其他遇到这个问题的人来说很重要。

By the definition of const, a function should not modify the state of an object. But if it calls another non-const member, the object's state might get changed, so it's disallowed.

I know you said you didn't want to hear about this, but I think it's important for others that happen upon the question.

£烟消云散 2024-10-07 01:17:45

const 成员方法的限制来自编译时。如果你能欺骗编译器,那么是的。

class CFoo
{ 
public:
    CFoo() {m_Foo = this;}
    void tee();

    void bar() const 
    { 
        m_Foo->m_val++;  // fine 
        m_Foo->tee();    // fine
    }
private:
   CFoo * m_Foo;
   int    m_Val;  

};

这实际上废除了const成员函数的目的,因此在设计新类时最好不要这样做。知道有一种方法可以做到这一点并没有什么坏处,特别是它可以用作这些旧类的解决方法,这些旧类在 const 成员函数的概念上没有很好地设计。

The restriction of const member methods are came from compile time. If you can fool the compiler, then yes.

class CFoo
{ 
public:
    CFoo() {m_Foo = this;}
    void tee();

    void bar() const 
    { 
        m_Foo->m_val++;  // fine 
        m_Foo->tee();    // fine
    }
private:
   CFoo * m_Foo;
   int    m_Val;  

};

This actually abolishes the purpose of const member function, so it is better not to do it when design a new class. It is no harm to know that there is a way to do it,especially it can be used as an work-around on these old class that was not well designed on the concept of const member function.

初心未许 2024-10-07 01:17:45

重载const

const int& Second() const
{
    return m_bar;
}

您可以添加此方法并保留原始的非常量版本。

Overload on const:

const int& Second() const
{
    return m_bar;
}

You can add this method and keep the original non-const version.

↘紸啶 2024-10-07 01:17:45

迭代器在这方面是类似的并且进行了有趣的研究。

const 迭代器通常是“非 const”迭代器的基础,并且您经常会发现 const_cast<>() 或 C 样式转换用于从基类中丢弃 const,并在子类中使用访问器。

编辑:
评论是

我有一个 zip 迭代器,其中 const 迭代器继承自非 const

这通常是错误的继承结构(如果你说我认为你是什么),原因是孩子不应该比父母受到更少的限制。

假设您有某种算法采用 zip 迭代器,将 const 迭代器传递给非 const 是否合适?

如果您有一个 const 容器,则只能要求它提供一个 const 迭代器,但是 const 迭代器是从迭代器派生的,因此您只需使用父级上的功能即可进行非 const 访问。

以下是遵循传统 stl 模型的建议继承的快速概述

class ConstIterator: 
    public std::_Bidit< myType, int, const myType *, const mType & >
{
  reference operator*() const { return m_p; }
}

class Iterator : public ConstIterator 
{
  typedef ConstIterator _Mybase;
  // overide the types provided by ConstIterator
  typedef myType * pointer;
  typedef myType & reference;

  reference operator*() const
  { 
    return ((reference)**(_Mybase *)this);
  }
}

typedef std::reverse_iterator<ConstIterator> ConstReverseIterator;
typedef std::reverse_iterator<Iterator> ReverseIterator;

iterators are similar in this and make an interesting study.

const iterators are often the base for 'non const' iterators, and you will often find const_cast<>() or C style casts used to discard const from the base class with accessors in the child.

Edit:
Comment was

I have a zip iterator where the const one inherits from the non-const

This would generally be the wrong inheritence structure (if your saying what I think you are), the reason being that children should not be less restrictive than parents.

say you had some algorithm taking your zip iterator, would it be appropriate to pass a const iterator to a non const ?

if you had a const container, could only ask it for a const iterator, but then the const iterator is derived from an iterator so you just use the features on the parent to have non const access.

Here is a quick outline of suggested inheritence following the traditional stl model

class ConstIterator: 
    public std::_Bidit< myType, int, const myType *, const mType & >
{
  reference operator*() const { return m_p; }
}

class Iterator : public ConstIterator 
{
  typedef ConstIterator _Mybase;
  // overide the types provided by ConstIterator
  typedef myType * pointer;
  typedef myType & reference;

  reference operator*() const
  { 
    return ((reference)**(_Mybase *)this);
  }
}

typedef std::reverse_iterator<ConstIterator> ConstReverseIterator;
typedef std::reverse_iterator<Iterator> ReverseIterator;
×纯※雪 2024-10-07 01:17:45

我发现自己试图调用一个继承的非常量成员函数,但由于我使用的 API,它实际上是 const。最后我选择了一个不同的解决方案:重新协商 API,以便我继承的函数是正确的 const。

并不总是可以协商对其他函数的更改,但在可能的情况下这样做似乎比需要使用 const_cast 更干净、更好,并且它也有利于其他用户。

I found myself trying to call a non-const member function that was inherited, but was actually const because of the API I was using. Finally I settled on a different solution: re-negotiate the API so that the function I inherit is properly const.

It won't always be possible to negotiate changes to others' functions, but doing so when possible seems cleaner and nicer than needing to use const_cast and it benefits other users as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文