Статичният метод Const променя стойностите

Експериментирах с ключовата дума const и се опитвах да извлека полезен подход от нея.

#include <iostream>

class A
{
  public:
  static const void modify(float& dummy)
  {
    dummy = 1.5f;
  }  
};

int main(int argc, char* argv[])
{
  auto a = 49.5f;

  A::modify(a);

  std::cout << a << std::endl; 

  return(0);
}

този код се компилира и работи, изходът е 1.5, очаквах грешка от компилатора, защото имам метод const, който се опитва да промени стойността на аргумент.

Какво ми липсва тук? Как мога да проектирам методи, които няма да променят стойностите на аргумента?


person user1802174    schedule 09.11.2012    source източник
comment
Ха, не знаех, че можеш да приложиш const към void.   -  person chris    schedule 09.11.2012
comment
всъщност имаш предвид static const void modify(const float& dummy)? в този случай не можете да промените манекена   -  person billz    schedule 09.11.2012
comment
@chris Как мога да напиша подобен метод, който да поддържа моите аргументи постоянни? защо не получавам предупреждението?   -  person user1802174    schedule 09.11.2012
comment
Хей, виж какво получавам от GCC: предупреждение: квалификаторите на типа се игнорират при тип връщане на функция [-Wignored-qualifiers]   -  person chris    schedule 09.11.2012
comment
@billz да, но съмнението ми е относно използването на const за типа на самия метод.   -  person user1802174    schedule 09.11.2012
comment
@user1802174, const се отнася само за нещото до него.   -  person chris    schedule 09.11.2012
comment
@chris Не получавам абсолютно нищо с g++-4.7 -std=c++11   -  person user1802174    schedule 09.11.2012
comment
@user1802174, вероятно е част от -Wall или -Wextra.   -  person chris    schedule 09.11.2012
comment
@chris, така че няма начин да се използва const на void методи?   -  person user1802174    schedule 09.11.2012
comment
@user1802174, Отнася се само за частта void, която е напълно безполезна, тъй като така или иначе не можете да направите нищо с void. Няма общ синтаксис, за да направите всеки параметър постоянен. Трябва ръчно да го приложите към всеки един.   -  person chris    schedule 09.11.2012
comment
@chris, тъй като така или иначе не можете да направите нищо с void. добре, не наистина, защото смисълът да направя всеки метод const е да получа този вид предупреждение и с void мога да направя същите грешки, които мога да направя с всички други подписи ...   -  person user1802174    schedule 09.11.2012


Отговори (2)


  1. Методът, който сте декларирали, не е const. Той връща const void (каквото и да е това), но самият той не е const-метод.

  2. Ако беше декларирано

    void modify(float& dummy) const
    

    това ще бъде константен метод, но все пак може да промени стойността на аргумента, защото на константен метод е разрешено да прави това. Единственото нещо, което не е позволено да прави, е да променя стойностите на членовете на класа, към който принадлежи.

  3. Обърнете внимание, че за да декларирам метод const, трябваше да премахна спецификацията static. Метод static никога не може да бъде const, тъй като статичен метод така или иначе не може да променя членове.

  4. Ако искате да попречите на функцията да променя своя аргумент, ще трябва да направите аргумента const:

    static void modify(const float& dummy)
    

За да илюстрираме какво може и какво не може да прави const-метод, ето клас, който има член и const-функция:

class A
{
  float my_member;
public:
  void modify(float& dummy) const
  {
    my_member = dummy; // attempt to modify member -> illegal
    dummy = 1.5f;      // modifies a non-const argument -> ok
  }  
};

Както можете да видите, той не може да променя член, но може да променя стойността на своя аргумент. Ако искате да предотвратите това, трябва да направите аргумента const:

class A
{
  float my_member;
public:
  void modify(const float& dummy) const
  {
    my_member = dummy; // attempt to modify member -> illegal
    dummy = 1.5f;      // attempt to modify a const reference -> illegal
  }  
};
person jogojapan    schedule 09.11.2012
comment
така че точка 4 е единственото решение за този и всички невалидни методи? - person user1802174; 09.11.2012
comment
Не, това е за предотвратяване на модифициране на аргумент. - person Denis Ermolin; 09.11.2012
comment
@user1802174, Това е единственото решение за всяка функция. Типът връщане няма нищо общо с това. - person chris; 09.11.2012
comment
@chris Бях убеден, че използването на const може да постави всеки аргумент в сейф. вероятно не е... - person user1802174; 09.11.2012
comment
@user1802174, Може поотделно, но наистина няма място да го поставите, което така или иначе няма да е двусмислено с нещо друго. - person chris; 09.11.2012
comment
Имах същата реакция относно "const void" - не съм сигурен какво трябва да бъде това. Тъй като 'const void' почти винаги е вероятно да е грешка, надявам се, че разумен компилатор ще предупреди, но това не изглежда да е така. - person Nik Bougalis; 09.11.2012
comment
@НикБ. Както (почти) винаги, когато сме озадачени от нещо, някой е бил озадачен преди: stackoverflow.com/questions/5057987/ - person jogojapan; 09.11.2012
comment
Знам, не бях озадачен; има смисъл да не се дефинира специален случай за 'const void' в стандарта. Но това не означава, че компилаторите не трябва да предупреждават за нещо подобно, дори ако строго погледнато, то е съвместимо със стандартите. - person Nik Bougalis; 09.11.2012

Не разбирате какво прави „const“ в този случай и как работи.

Първо, в C++ статичните членски функции не могат да бъдат const. Функцията, която показвате, връща тип 'const void' (дали това има смисъл и дали компилаторът трябва да предупреждава е друга тема).

Второ, параметърът, който променяте, не е const. Ако „modify“ не беше статична функция и имаше модификатор „const“ във функцията, dummy все още можеше да бъде модифициран:

void modify_nonstatic(float &dummy) const
{
    dummy = 1.5f; // perfectly fine - dummy isn't a member of
                  // the class and can be modified
}

Ако искате параметърът да бъде const, направете параметъра const:

static void modify(const float &dummy) 
{
    dummy = 1.5f; // fail! you can't modify a const.
}

void modify_nonstatic(const float &dummy)
{
    dummy = 1.5f; // fail! you can't modify a const.
}
person Nik Bougalis    schedule 09.11.2012
comment
благодаря, за съжаление поради ниската си репутация не мога да гласувам за това, но това е добър отговор, благодаря. - person user1802174; 09.11.2012
comment
Без притеснения – не става въпрос за гласовете „за“; става дума за въпросите и отговорите. - person Nik Bougalis; 09.11.2012