функции с константными аргументами Перегрузка (продолжение) - PullRequest
1 голос
/ 10 сентября 2010

Это продолжение предыдущего вопроса

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

Обновленный код: (Соответствует и работает)

#include <iostream>
 using std::cout;

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

 int main ()
 {   
         Test obj;
         int variable=0;  
         int output;
     do{ 
         output=obj.foo(3);        // Call the const function 
         cout<<"output::"<<output<<std::endl;
         output=obj.foo(variable); // Want to make it call the non const function 
         cout<<"output::"<<output<<std::endl;
         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;
 }   

Вывод (я получаю):

NON CONST
output::4
NON CONST
output::1
NON CONST
output::4
NON CONST
output::2
NON CONST
output::4
NON CONST
output::3
NON CONST
output::4
NON CONST
output::4
NON CONST
output::4
NON CONST
output::5

Вывод (я хотел / имел в виду)

CONST
output::3
NON CONST
output::1
CONST
output::3
NON CONST
output::2
CONST
output::3
NON CONST
output::3
CONST
output::3
NON CONST
output::4
CONST
output::3
NON CONST
output::5

Надеюсь, я изложил свой вопрос лучше.Я знаю другие способы сделать это.но возможно ли это.

Ответы [ 6 ]

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

В С ++ функции подписи

int Test::foo (const int a) const

и

int Test::foo (int a) const

считаются полностью идентичными.

Причина, по которой const в параметре игнорируется, заключается в том, что он никак не может повлиять на вызывающего. Поскольку параметр передается по значению, создается копия значения, предоставленного вызывающей стороной. Для вызывающей стороны не имеет значения, может ли вызываемая функция изменить эту копию или нет. По этой причине C ++ игнорирует const -квалификацию верхнего уровня для параметров функции (верхнего уровня const не может произойти при передаче ссылки) и даже доходит до того, что int foo(int); считается правильным прототипом функция

int foo(const int)
{
    /* ... */
}

Короче говоря, в C ++ невозможно перегрузить функцию на постоянство параметров функции (значения). Чтобы получить желаемый результат, вы можете рассмотреть возможность использования неконстантного ссылочного параметра для вашей неконстантной перегрузки.

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

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

int foo(int a);
int foo(const int a);

Вы получите ошибку.

Во втором случае вы думаете, что foo ожидает const int в качестве аргумента, но нет.const привязан к a, а не int.Так что он говорит, что foo ожидает int, вы можете ссылаться на него, используя a, и это будет константой: вам не разрешено изменять a.Вот почему const (для параметра) не отображается в сигнатуре функции (которая будет отличаться для ссылки).
Константа вне функции относится к вызываемому объекту, так что это часть сигнатуры

int foo(int a); # type => int (Test::*)(int)
int foo(const int a) const; # => int (const Test::*)(int)

int foo(const int a) ; # => int (Test::*)(int)
int foo(int a) const; # => int (const Test::*)(int)

(я не уверен на 100% в синтаксисе типа, так что не комментируйте его, это просто идея)

Как вы можете видеть, const удаляется сa.Вы также можете написать это int const a, даже если это не стандартный способ сделать это, это совершенно законно.

Кстати, ваш код никогда не будет делать то, что вы ожидаете, вы должны использовать ссылку наint, чтобы изменить его

int Test::foo(int &a) ...
2 голосов
/ 10 сентября 2010

Хорошо, вот как это работает:

Когда вы вызываете функцию, значение параметров передается в функцию.Если вы передадите значение, то это значение будет тем, что получит функция.Если вы передадите указатель, то ваша функция получит указатель.

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

Просто для примера, все эти вызовы функций выглядят ИДЕНТИЧНО для функции, которая их получает:

int i=1;
int* b = new int;
*b = 4;
func(5);
func(3+2);
func(i+4);
func(*b+1);

Поэтому, чтобы ответить на ваш вопрос, то, что вы делаете, невозможно.

EDIT: чтобы изменить переменную, перегрузите функцию с помощью int и указателя на int.Передавая адрес значения int в функцию, ваша функция может изменить его.

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

Да, я не могу заставить его вызывать константную версию - если я не сделаю это:

const Test obj2;
output=obj2.foo(3);        // Call the const function 

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

Интересно.

0 голосов
/ 11 октября 2010

Просто уточнение. Однако нам разрешено перегружать указатели с аргументами const и без них в функциях, верно?

Как в,

int Test::foo (const int* a);
int Test::foo (int* a);

Чем это отличается?

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

Преобразование const int в строку, перегрузка foo строкой и преобразование обратно ...

Не стесняйтесь уничтожить мой ответ и комментарии.

...