是否是一个好的做法,使一个方法修改const类以外的数据? [英] Is it a good practice to make a method which modifies data outside the class const?

查看:215
本文介绍了是否是一个好的做法,使一个方法修改const类以外的数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想问一个关于方法的const正确性的问题。让我举例说明一下情况。

  class MyClass 
{
public:
...
void DiscussedMethod(){otherClass-> NonConstMethod(); }

private:
OtherClass * otherClass;
};

我有一个类 MyClass 指向 OtherClass 。在 DiscussedMethod 中调用 OtherClass :: NonConstMethod ,修改一些可见数据。



我想知道,是否一个好的做法是使 DiscussedMethod const 因为它不修改任何成员数据)?这是一个坏的做法吗? c> / code>并且在 NonConstMethod 中修改了一些 MyClass c> MyClass 成员数据将在 DiscussedMethod 调用期间更改)。那么使 DiscussedMethod const 这是一个不好的做法吗?



就我已经能够找到的,一个方法上的 const 大多是一个代码记录的东西,所以我可能倾向于不做 DiscussedMethod const ,但我想听听您的意见。



EDIT:有些回复会考虑 otherClass 指向的对象是否由 MyClass 对象。在我工作的情况下不是这样的情况。假设两个对象并排独立存在(具有彼此修改的能力)。我认为这个比喻很好地描述了我的情况。



例如考虑像双向链表,每个元素是一个类,保持指向它的邻居和成员变量 color 。它有方法 MakeNeighboursRed ,它改变其邻居的颜色,但不影响调用对象的状态本身。我应该考虑使这个方法 const



如果有一些可能性 MakeNeighboursRed 会调用邻居的 MakeNeighboursRed 。因此,最后被调用 MakeNeighboursRed 的对象的状态最初也会改变。



我想感谢大家的意见: - )

解决方案

如果 MyClass 拥有 OtherClass 实例我不会使 DiscussedMethod 常量。



类,管理资源也是如此。也就是说标准容器不使用const函数返回非const引用或指向管理存储器的指针,尽管它是可能的(因为保存资源的实际指针不被修改)。



考虑

  class MyClass 
{
public:
bool a()const {return otherClass-> SomeMethod(); }
void b()const {otherClass-> NonConstMethod(); }
private:
OtherClass * otherClass;
};

void foo(MyClass const& x)
{
cout< boolalpha< x.a()<< endl;
x.b(); //可能如果b是const函数
cout<< boolalpha< x.a()<< endl;
}

foo 打印两个不同的值,尽管 foo 的实现者可能希望对const对象的两个函数调用具有相同的行为。



为了说明:



根据标准,以下是无效的,因为 operator [] 返回 std :: vector< T> :: const_reference ,它是值类型的常量引用。

  std :: vector< int> const a = {/ * ... * /}; 
a [0] = 23; //不可能,内容是状态的一部分

这个函数的一个签名,即 referece operator [](size_t i)const; ,因为操作不改变向量的内部指针,而是它们指向的内存。



但是由向量管理的内存被认为是向量状态的一部分,因此通过const向量接口修改是不可能的。



如果向量包含指针,这些指针仍然是不可修改通过public const向量接口,虽然存储在向量中的指针很可能是非常量,并且很可能改变它们的内存指向。

  std :: vector< int *> const b = {/ * ... * /}; 
int x(2);
b [0] =& x; //不可能,b是const
* b [0] = x; //可能,因为value_type是int * not int const *


I would like to ask a question about methods' const-correctness. Let me illustrate the situation.

class MyClass
{
public:
    ...
    void DiscussedMethod() { otherClass->NonConstMethod(); }

private:
    OtherClass *otherClass;
};

I have a class MyClass which keeps a pointer to OtherClass. In DiscussedMethod it calls OtherClass::NonConstMethod which modifies some visible data.

I would like to know, whether it would be a good practice to make the DiscussedMethod const (since it doesn't modify any member data)? Would it be a bad practice? Or is both fine?

What if the OtherClass kept a pointer to the MyClass and in NonConstMethod modified some of the MyClass' data (meaning that the MyClass member data would change during the DiscussedMethod call). Would it be a bad practice to make the DiscussedMethod const then?

As far as I've been able to find out, the const on a method is mostly a code documenting thing, so I would probably lean toward to not making the DiscussedMethod const, but I would like to hear your opinions.

EDIT: Some replies take the into account whether the object pointed to by otherClass is owned by the MyClass object. This is not the case in the scenario I'm working with. Lets say that both objects exist independently side by side (with the ability to modify each other). I think this analogy describes my situation quite well.

For example consider something like doubly-linked list, where each element is a class that keeps pointer to its neighbours and member variable color. And it has method MakeNeighboursRed which changes the color of its neighbours but doesn't affect the calling object's state itself. Should I consider making this method const?

And what if there was some possibility that MakeNeighboursRed would call neighbour's MakeNeighboursRed. So in the end the state of the object for which MakeNeighboursRed has been called originally would change as well.

And I would like to thank you all for your opinions :-)

解决方案

If MyClass owns the OtherClass instance i wouldn't make DiscussedMethod constant.

The same goes for classes, managing resources. I.e. the standard containers do not return non const references or pointers to the managed memory using const functions, although it would be "possible" (since the actual pointer holding the resource is not modified).

Consider

class MyClass
{
public:
    bool a() const { return otherClass->SomeMethod(); }
    void b() const { otherClass->NonConstMethod(); }
private:
    OtherClass *otherClass;
};

void foo (MyClass const &x)
{
    cout << boolalpha << x.a() << endl;
    x.b(); // possible if b is a const function
    cout << boolalpha << x.a() << endl;
}

The foo could print two different values although an implementor of foo would probably expect that two function calls on a const object will have the same behaviour.

For clarification:

The following is invalid according to the standard since the const version of operator[] returns std::vector<T>::const_reference which is a constant reference to the value type.

std::vector<int> const a = { /* ... */ };
a[0] = 23; // impossible, the content is part of the state of a

It would be possible if there was only one signature of this function, namely referece operator[] (size_t i) const;, since the operation does not alter the internal pointers of the vector but the memory they point to.

But the memory, managed by the vector is considered to be part of the vectors state and thus modification is impossible through the const vector interface.

If the vector contains pointers, those pointer will still be unmodifiable through the public const vector interface, although the pointers stored in the vector may well be non const and it may well be possible to alter the memory they point to.

std::vector<int*> const b = { /* ... */ };
int x(2);
b[0] = &x; // impossible, b is const
*b[0] = x; // possible since value_type is int* not int const *

这篇关于是否是一个好的做法,使一个方法修改const类以外的数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆