【问题标题】:functions with const arguments Overloading ( Follow up)带有 const 参数的函数重载(跟进)
【发布时间】:2010-09-10 10:29:31
【问题描述】:

这是Previous Question的跟进

它变得非常复杂,所以我开始一个新线程以使我的观点更清楚。(不想删除以前的线程,因为其他提供有价值反馈的人不会失去他们获得的声誉点数)

更新的代码:(符合并有效)

#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

希望我能更好地提出我的问题。我知道其他方法可以做到这一点。但这可能吗?

【问题讨论】:

  • 嗯,这是我第一次看到有人在实际代码中使用 do-while。
  • 不知道这是否实用..我把它当作脑筋急转弯并试图让我的脑袋绕开它..除了弄脏我们的手还有什么其他的学习方式;)跨度>
  • 我不明白这不是您之前问题的重复。由于int foo(int);int foo(const int); 是相同的函数签名,如果您在类声明中使用int foo(int);int foo(int) const; 这两个签名,您的问题会更清楚。

标签: c++ class overloading


【解决方案1】:

在 C++ 中,函数签名

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++ 中,不可能在(值)函数参数的常量上重载函数。 要获得所需的输出,您可以考虑为非常量重载使用非常量引用参数。

【讨论】:

  • @mb14:我不明白你的评论。你能详细说明一下吗?
【解决方案2】:

const(或非const)函数的调用不依赖于参数的常量,而只依赖于被调用对象的常量(在我们的例子中为obj)。重载需要不同的类型,而 (non-const const) 不是,所以我认为你不能在这样做的时候重载。 (因为您正在定义一个 const 和一个非常量方法,但这不是重载。) 为了说服自己,试着把声明末尾的 const 去掉,看看是否允许声明

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

你会得到一个错误。

在第二种情况下,您认为 foo 期望 const int 作为参数,但不是。 const 绑定到 a 而不是 int。所以它说的是 foo 期望一个 int,你可以使用 a 来引用它,那将是 const :你不能修改 a。这就是为什么(参数的)const 没有出现在函数签名中的原因(这对于参考来说会有所不同)。
函数外的 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% 确定,所以不要评论它,这只是提供一个想法)

如您所见,consta 删除。你也可以写int const a,即使不是标准的写法,也是完全合法的。

顺便说一句,你的代码永远不会做你所期望的,你应该使用对 int 的引用来修改它

int Test::foo(int &a) ...

【讨论】:

  • 只是我的观点,为什么即使最后使用 const 编译器也不给出错误,那似乎有点多余......是的,我在之前的试验中尝试过。
  • 因为在最后加上const,就是定义了一个const方法,可以定义同名同参数的const和non-const方法。但这不是超载。要调用 const 方法,请将其转换为 const 对象:static_cast&lt;Test&amp;&gt;(obj).foo(3)。但在现实生活中,我肯定会建议为您的方法使用两个不同的名称,因为它们做不同的事情。
  • @mb14..如果你检查了 ragster 提到的内容..你有点得到正确的输出值(但如果我不打印 CONST 和 NON CONST)..hmm..所以我还没有放弃希望:)..是的,在 RL 中我会做不同的事情。
  • @MrProg... 我想知道编译器是否认为 'const' 无关紧要,因为参数是按值传递的。
  • @skimobear: const 是相关的,但意味着你不能修改值(在函数内部)。
【解决方案3】:

好的,这就是它的工作原理:

当你调用一个函数时,参数的值被传递给函数。如果你传递一个值,那么这个值就是函数得到的值。如果你传递一个指针,那么你的函数就会得到一个指针。

当你的函数接收到参数时,它看到的只是一个整数值。它无法确定该值的来源,也不能是静态的或非静态的。这些属性属于指针,表示是否可以改变指针所指向的值,而不是指针本身。

为了更好地衡量,所有这些函数调用看起来与接收它们的函数相同:

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

所以要回答你的问题,你正在做的事情是不可能的。

编辑:要更改变量,请使用 int 和 int 指针重载函数。通过将 int 值的地址传递给函数,您的函数可以更改它。

【讨论】:

  • 是的,我不希望这种情况发生..*一直在思考*
  • 这个答案只使用了 C++ 的 C 子集。在 C++ 中,最好使用引用。所有这些调用都可以由采用const int &amp; 的函数或采用int 的函数匹配(编译器在解析声明时会丢弃传递值中的常量)。它们都不匹配采用非常量引用的函数的参数。
【解决方案4】:

是的,我不能让它调用 const 版本 - 除非我这样做:

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

无论传入什么参数,只要能调用非const,都会。如果你有一个 const 对象,它会调用函数的 const 版本。

有趣。

【讨论】:

    【解决方案5】:

    只是一个澄清。但是,我们可以在函数中重载带有和不带有 const 参数的指针,对吧?

    如,

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

    这有什么不同?

    【讨论】:

      【解决方案6】:

      const int 转换为字符串,用字符串重载foo 并转换回...

      随意破坏我的答案和 cmets。

      【讨论】:

      • @Cedric ..如果您看起来那不是我的意思..我想使用相同的数据类型..在您提到的情况下,我可以说一个 const 字符串和可能会有所不同的字符串。 PS。我没有反对意见
      • 明白,只是个玩笑,因为你看起来“不顾一切”想要让它发挥作用......
      • 哈哈..我把它当作一个挑战..如果检查它来自另一个问题的链接,那么我只是想打破界限。
      猜你喜欢
      • 2011-04-10
      • 1970-01-01
      • 2012-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多