【问题标题】:What are the things which are decisive in call during function overloading?函数重载期间调用的决定性因素是什么?
【发布时间】:2012-02-18 18:13:55
【问题描述】:

我只是想知道在执行期间进行函数调用的决定性因素是什么 超载。据我所知,它的参数签名,传递的参数数量 其中起着重要作用。但是是否还有 const 部分也起着重要的作用 是否参与超载。第一个和第二个函数的重载工作正常,但如果添加 在传递参数中以 const 作为特征的第三个函数,我得到编译错误。 int A::sum(int, int) and int A::sum(int, int) cannot be overloaded。只需给出类的代码 sn-p:

class A
{
    private:
    int x;
    int y;

    public:
    int sum ( int a, int b )
    {
        cout << " Inside 1st ";
        return (a+b) ;
    }

    int sum (int a ,int b) const
    {
        cout << " Inside 2nd ";
        return (a+b) ;
    }

    int sum (const int a ,const int b)
    {
        cout << " Inside 3rd ";
        return (a+b) ;
    }

    A(){x=0;y=0;}
    ~A(){};
}; 

当我声明普通对象并调用 sum 时,第一个函数被调用,如果是 const 对象,则调用第二个 sum。这完全没问题。但是,如果我编写第一个和第三个函数,这都会成为一个问题。为什么会这样?

【问题讨论】:

  • 就像一个注释,当你声明一个函数为void f(T);时,你可以定义它为void f(T const x) { /* ... */ }。换句话说,值参数的常量是一个实现细节,因为它只影响函数作用域内局部变量的常量,与函数的调用方式无关。跨度>

标签: c++ overloading


【解决方案1】:

您可以在const-ness 上重载,但仅限于它真正产生影响的地方。我的意思是“实际上有所作为”?好吧,如果你声明

void foo(char *ptr);
void foo(const char *ptr);

const 很重要:您是说foo 的一个重载保证不会修改ptr 指向的内存,而另一个则不会。但是如果你声明

void foo(int x);
void foo(const int x);

const 无关:标量参数总是按值传递,因此foo 的假设变体都不能在其调用者中修改x 的值,即使它想要。因此,C++ 标准说const 被丢弃,这是同一个函数的两种不同声明,其中一种是错误的。

const 相对于* 的位置很重要。指针本身就是一个标量,所以这也是同一个函数的两个声明:

void foo(char *ptr);
void foo(char *const ptr);

因为这里const 限定了指针本身而不是它指向的对象。

这给我们带来了方法:在方法声明的参数列表之后的 const 限定符适用于 this 指向的对象,并且可以重载:

struct A
{
  int foo (char *ptr);
  int foo (char *ptr) const;
  int foo (const char *ptr);
  int foo (const char *ptr) const;
};

您应该将这些声明视为在内部重写为:

struct A {};
int A_foo (A *this, char *ptr);
int A_foo (const A *this, char *ptr);
int A_foo (A *this, const char *ptr);
int A_foo (const A *this, const char *ptr);

然后一切都按照重载函数的正常规则运行。

【讨论】:

  • Zack 的精彩解释,将实际检查一下。希望它能消除我所有的疑虑。
【解决方案2】:

const 和非const 函数可以重载。(const 跟在函数后面)
即它是函数重载的有效标准。

但是,您示例中的函数不能基于函数参数的constness 进行重载,因为参数的常量性根本不重要。函数参数是按值传递的,函数接收一个 副本
函数重载需要同名函数之间应该有一些区分标准,除非const on 参数实际上使得被重载的函数从编译器的角度来看是不同的,使用函数的const-ness重载不允许参数。

前者是可能的,因为,
如果您有一个 const 对象,那么您只能在其上调用 const 函数。因为非 const 函数必然会修改类成员,因此在 const 对象上调用它是语义错误,会导致编译错误。

如果你有一个普通的 on-const 对象,那么 const 和非常量版本的函数都可以在实例上调用。编译器会选择最合适的版本,即非常量版本。

【讨论】:

  • 编译器不允许我们根据参数constness进行重载有什么具体原因吗?
  • 我想知道并且您可能可以回答的事情是重载/继承和访问控制。我的经验表明,如果 foo 在基类中为 protected,则在派生类中设置 foo public 不会使其重载。但一般规则是什么?
  • @Als 谢谢 Als,我明白了你的意思,但我的问题是为什么编译器不允许我使用传入 const 参数的第三个函数?
  • 这个答案相当具有误导性——你可以重载参数的常量性,但只有当const 真正重要时,例如当它是“指向 T 的指针”与“指向 const T 的指针”时。在参数列表之后重载constis 重载参数的常量:隐式this 参数。
  • @Ritesh:因为它没有任何区别,因为您的情况下的参数是按值传递的。您的函数接收正在传递的原始参数的副本,因此 const 在这里无关紧要。
猜你喜欢
  • 2015-04-07
  • 2020-08-06
  • 1970-01-01
  • 2021-02-18
  • 1970-01-01
  • 2021-03-20
  • 1970-01-01
  • 1970-01-01
  • 2020-10-10
相关资源
最近更新 更多