2017-01-25 10 views
1

Я знаю, что объект const не может вызвать функцию-член не const. Это говорит так в C++ 14 стандарта (ISO/IEC 14882: 2014) Раздел 9.3.2, пункт 3:Const Object, Const Member Function и Mutable Variable в C++

резюме квалифицированных функция-член может быть вызван на объектно-выражения (5.2 .5) только в том случае, если объектное выражение является cv-квалифицированным или менее-cv-квалифицированным, чем функция-член.

Имеет ли это ограничение смысл, если функция-член ничего не изменяет? Или, если функция-член изменяет изменчивую переменную? Например:

class My_Class { 
    public: 
     mutable int value; 
     void function(int x) const { value = x; } //  Correct 
     //void function(int x)  { value = x; } // Not Correct 
     My_Class() : value(0) {} 
}; 

int main(){ 

    const My_Class obj; 
    obj.function(1); 

    return 0; 
} 

В данном конкретном случае, если функция const, программа правильна и функция может изменить переменную const объекта. Если функция не const, программа неверна. Поэтому, в конце концов, мне нужно написать const, чтобы иметь возможность что-то изменить, что должно быть противоположной целью const.

Кто-нибудь знает, почему это правило спроектировано таким образом?

+2

Объекты 'const' не подлежат изменению. Ничего не поделаешь. 'mutable' - это просто чит и предназначен для использования в переменных-членах, которые на самом деле не являются частью внутреннего состояния объекта (например, мьютекс, который должен быть заблокирован или разблокирован независимо от' const'). – DeiDei

+0

re. «Если функция не является константой, программа неверна» ... const используется для обозначения концептуальной идентичности, а не простоты байта. неконстантные функции не должны что-то менять. – ccpgh

ответ

2

Имеет ли смысл [раздел 9.3.2, абз. 3 из], если функция-член ничего не изменяет? Или, если функция-член изменяет изменчивую переменную?

Да, это так. Вызывающий функции не может вообще знать, изменяет ли функция какой-либо не изменяемый элемент. Он знает, является ли функция const или нет, поэтому компилятор может принять решение только на основе этого.

Неконстантная функция может изменить непеременное состояние, поэтому вы, очевидно, не можете называть его объектом const. Независимо от того, изменяет ли функция не const, состояние является нерелевантным, поскольку это деталь реализации, которая недоступна при принятии решения о разрешении вызова. Другими словами, константа является частью интерфейса функции, а реализация функции не является частью интерфейса. Интерфейс функции полностью определяется ее объявлением.

Пример:

struct C { 
    mutable int a; 
      int b; 
    void do_something(); 
}; 

const C c; 
c.do_something(); 

Имеет ли смысл разрешить вызов do_something? Может ли это повлиять на то, что do_something не может изменить b? Как мы можем предположить, что do_something не изменяет b?

Ответы: это не имеет смысла. Это не влияет. Мы не можем сделать такое предположение.

Написание функции не const-члена, которая не модифицирует какое-либо не изменяемое состояние - по крайней мере, потенциально или допускает такую ​​модификацию косвенно путем возврата не const-ссылки/указателя на this - мало смысла, хотя стандарт позволяет это делать ,

В конце концов, мне нужно написать const, чтобы иметь возможность что-то изменить, что должно быть противоположной целью const.

Это может показаться оксюмороническим, но это потому, что это упрощение. Вам нужно написать const, чтобы иметь возможность изменять изменяемое состояние объекта const. Созданная вами константа объявляет, что вы не изменяете какое-либо не изменяемое состояние, и это объявление дает разрешение называть его в объектах const.

Ваша запрошенная функция non-const по-прежнему правильная для использования с объектами, не являющимися константами.

+0

Нет ограничений не разумно, и не существует! Кажется, что OP думает, что функция non-const * не может * изменять изменяемый член. Конечно, это бессмыслица. –

+0

Перечитывая вопрос: ограничение в стандарте имеет полное представление о конечно. Проблема в том, что OP читает в нее. –

+1

@MartinBonner Я не совсем уверен, думает ли OP об этом. Я вижу, что им трудно отличить разделение между интерфейсом функции от реализации функции. Я уточнил, какую чувствительность я имею в виду. – user2079303

2

Существует фундаментальное непонимание в вашем вопросе:

class My_Class { 
    public: 
     mutable int value; 
     void function(int x)  { value = x; } // Absolutely fine 
     My_Class() : value(0) {} 
}; 

mutable не означает, что «может быть изменен только в функции в const члена». Это означает, что «может быть изменен даже в функции const».

+0

Я знаю, что ваш код в порядке с объектом, отличным от 'const'. Однако в моем примере объект «const» намеренно. Таким образом, функция non-'const' не подходит, если она вызывается объектом 'const' (как в моем примере). Насколько мне известно, это неверно. –

+0

@JL: Вы сказали: «Итак, в конце концов, мне нужно написать const, чтобы иметь возможность что-то изменить ...»: Нет! Нет необходимости писать const, чтобы иметь возможность что-то модифицировать. 'mutable' говорит:« Вы можете изменить * этот * бит, даже если охватывающий объект изменчив. –

+0

Я понимаю вашу точку зрения, и я уже знал об изменчивости. Однако предложение «Так что в конце мне нужно написать const я могу изменить что-то ... »остается верным, на мой взгляд. Если я не использую' const', программа не компилируется, потому что это неверно в соответствии со стандартом. Если я использую 'const', он компилирует и я могу изменить переменную.Как сказал @ user2079303, это упрощение, но в практическом смысле для этого конкретного случая, это то, что происходит. В очередной раз благодарим за помощь. –

1

mutable ключевого слова,

Относится к нестатическим членам класса в нереференсном неконстантном типе и указует, что элемент не влияет на внешний видимое состояние класса (как часто используется для мьютексы , памятные тайники, ленивая оценка и инструменты доступа). изменяемые члены экземпляров const-класса могут быть изменены

Вы задаете вопрос о правильности ключевого слова C++. Я чувствую примеры в этом определении, даю положительное доказательство того, что такое ключевое слово необходимо, и что mutable, как предполагают разработчики языка, является благом для нас.