可以基于引用形参类型重载构造函数吗?

Can we overload Constructor based on reference parameter type?

本文关键字:类型 形参 重载 构造函数 引用 于引用      更新时间:2023-10-16

我知道我们不能像下面这样重载构造函数(唯一的区别是初始化列表):

myClass(const INT& oInt,const STRING& oStr):I(oInt),STR(oStr){
        cout << "my Class Object Created with I : " << I << " STR : " << STR << endl;
}
myClass(const INT& oInt,const STRING& oStr){
        I=oInt;
        STR=oStr;
        cout << "my Class Object Created with I : " << I << " STR : " << STR << endl;
}

但是假设我想重载构造函数为:

myClass(const INT& oInt,const STRING& oStr):I(oInt),STR(oStr);
myClass(const INT oInt,const STRING oStr);

。根据不同的参数类型one as reference type,其他as normal type

我指的是我以前的问题:重载类成员函数

可以实现吗?

My Code is:

#include <iostream>
#include <string>
using namespace std;
class INT{
int i;
    public:
INT(int i=0):i(i){
        cout << "INT Class Object Created with i : " << i << endl;
}
~INT()
{
    cout << "INT Class Object Destructed with i :" << i << endl;
}
INT(const INT& I){
    i=I.i;
        cout << "INT Class Copy Constructor called for i : "<< i << endl;
}
INT& operator= (const INT& I){
    i=I.i;
        cout << "INT Assignment operator called for i : "<< i << endl;
    return *this;
}
friend ostream& operator << (ostream& os,const INT& I){
        os << I.i ;
    return os;
}
};

class STRING{
    string str;
    public:
STRING(string str=""):str(str){
    cout << "STRING Class Object Created with str : " << str << endl;
}
~STRING()
{
    cout << "STRING Class Object Destructed with str :" << str << endl;
}

STRING(const STRING& S){
    str=S.str;
        cout << "STRING Class Copy Constructor called for str : "<< str << endl;
}
STRING& operator= (const STRING& S){
    str=S.str;
        cout << "STRING Assignment operator called for str : "<< str << endl;
    return *this;
}
friend ostream& operator << (ostream& os,const STRING& S){
        os << S.str ;
    return os;
}
};

class myClass{
    INT I;
        STRING STR;
    public:
myClass(const INT& oInt,const STRING& oStr):I(oInt),STR(oStr){
    cout << "my Class Object Created with I : " << I << " STR : " << STR << endl;
}
myClass(const INT oInt,const STRING oStr){
        I=oInt;
    STR=oStr;
    cout << "my Class Object Created with I : " << I << " STR : " << STR << endl;
}

~myClass()
{
    cout << "my Class Object Destructed with I : " << I << " STR : " << STR << endl;
}
};


int main()
{
       INT iObj(5);
       STRING strObj("Alina Peterson");

      cout << "nn======================================================nn" << endl;
      myClass myObj(iObj,strObj);
      cout << "nn======================================================nn" << endl;
    return 0;
}
我得到的错误是:
$ g++ -g -Wall CPP.cpp -o CPP
CPP.cpp: In function ‘int main()’:
CPP.cpp:116:32: error: call of overloaded ‘myClass(INT&, STRING&)’ is ambiguous
       myClass myObj(iObj,strObj);
                                ^
CPP.cpp:116:32: note: candidates are:
CPP.cpp:86:1: note: myClass::myClass(INT, STRING)
 myClass(const INT oInt,const STRING oStr){
 ^
CPP.cpp:81:1: note: myClass::myClass(const INT&, const STRING&)
 myClass(const INT& oInt,const STRING& oStr):I(oInt),STR(oStr){
 ^

如何强制转换构造函数,使其能够区分重载构造函数的两个版本?

您可以在T const&T上重载构造函数,但编译器无法选择构造函数,从而导致一对不可调用的构造函数:对于任何可行的参数,两者都不如另一个好。此外,你不能显式地选择构造函数:构造函数不是普通的函数,你不能强制转换它们。因此,在T const&T上重载构造函数是完全无用的。然而,可以基于右值重载:让一个构造函数取T const&,另一个取T&&

也许你应该问你想要实现什么而不是你如何尝试实现它…

假设你有两个函数:

void foo(int const x) {}
void foo(int const& x) {}

当你呼叫

foo(10);

编译器不能消除两个重载函数之间的歧义。

当你有:

void foo(int& x) {}
void foo(int const& x) {}

并调用相同的foo(10);,编译器将正确地选择第二个。

你有什么

myClass(const INT& oInt,const STRING& oStr);
myClass(const INT oInt,const STRING oStr);

类似于第一对函数。

您应该问自己的问题是,是什么需求导致您创建这样的重载。它们是真正的需求吗?除非您的需求是一些不寻常的东西,否则您应该能够只管理其中的一个。

call

myClass(const STRING& oStr, const INT& oInt):I(oInt),STR(oStr) {}

你可以做以下任何一个

INT iObj(5);
STRING strObj("Alina Peterson");
INT& x = iObj;
myClass myObj(x, strObj);

myClass myObj(*(&iObj), strObj);
对于另一个构造函数

,我认为你不能调用它,总是会导致错误

您无法回避这样一个事实:您不能有两个函数(构造函数或其他)接受相同的参数。如果你这样做,你就没有重载,你只是复制了函数。对于按引用而不是按值传递,编译器不会做出特殊的异常。

作为一种解决方法,你可以在重载的构造函数中添加一个额外的未使用的形参(如bool)。