Функции с аргументами const и перегрузкой - PullRequest
4 голосов
/ 10 сентября 2010

Попробовал StackerOverflow qn , поэтому я подумал, почему бы не перегрузить функцию, и я получил немного другой код, но он говорит, что функция не может быть перегружена. Мой вопрос почему? или есть другой способ?

 #include <iostream>
 using std::cout;

 class Test {
         public:
         Test(){ }
         int foo (const int) const;
         int foo (int );
 };

 int main ()
 {
         Test obj;
         Test const obj1;
         int variable=0;
     do{
         obj.foo(3);        // Call the const function 
          obj.foo(variable); // Want to make it call the non const function 
         variable++;
             usleep (2000000);
        }while(1);
 }

 int Test::foo(int a)
 {
    cout<<"NON CONST"<<std::endl;
    a++;
    return a;
 }

 int Test::foo (const int a) const
 {
    cout<<"CONST"<<std::endl;
    return a;
 }

Ответы [ 3 ]

21 голосов
/ 10 сентября 2010

Вы не можете перегружать, основываясь только на постоянстве не указателя, не ссылочного типа.

Подумайте, например, если бы вы были компилятором. Столкнулся с линией:

 cout <<obj.foo(3);

какую функцию вы бы назвали?

При передаче по значению значение копируется в любом случае. Значение const в аргументе относится только к определению функции.

16 голосов
/ 10 сентября 2010

§13.1, где Стандарт обсуждает объявления, которые не могут быть перегружены, -

Объявления параметров, которые отличаются только при наличии или отсутствии const и / или volatile эквивалентны. То есть const и volatile спецификаторы типа для каждого параметра тип игнорируется [...]

Только постоянные и летучие спецификаторы типа на самом внешнем уровне спецификации типа параметра игнорируются таким образом; const и изменяемые спецификаторы типа, скрытые в спецификация типа параметра значительный и может быть использован для различать перегруженную функцию деклараций. [...]

при определении, какая функция быть объявленным, определенным или вызванным. «В частности, для любого типа Т, «Указатель на T», «указатель на const T» и «указатель на летучий Т» являются рассматриваются различные типы параметров, как «ссылка на Т», «ссылка на const T »и« ссылка на летучий Т.»

РЕДАКТИРОВАТЬ 2:

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

Способ их успешной перегрузки зависит от квалификации cv подразумеваемого первого параметра в случае вызовов функций-членов, как показано. Функция-член const может быть вызвана только в том случае, если выражение объекта, используемое для вызова перегруженной функции-члена, также является const. Когда неконстантное выражение объекта используется для вызова перегруженного вызова функции-члена, предпочтение отдается неконстантной версии, так как она является точным соответствием (вызов перегрузки функции-члена const потребует квалификации cv первого подразумеваемого аргумента)

#include <iostream> 
using std::cout; 

class Test { 
        public: 
        Test(){}
        int foo (const int) const; 
        int foo (int ); 
}; 

int main () 
{ 
        Test obj;
        Test const objc;  // const object
        obj.foo(3);       // calls non const overload, object expression obj is non const
        objc.foo(3);      // calls const overload, object expression objc is const
} 

int Test::foo(int a) 
{ 
   a++; 
   return a; 
} 

int Test::foo (const int a) const
{ 
   return a; 
} 
1 голос
/ 10 сентября 2010

Как объясняется в ответе на другой вопрос, два foo не отличаются, поскольку имеют эквивалентные определения параметров.

...