我们可以根据引用参数类型重载构造函数吗?

时间:2014-05-05 15:55:05

标签: c++ constructor constructor-overloading

我知道我们不能像下面那样重载构造函数(只有区别是初始化列表):

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

我指的是我的旧问题: Overloading Class Member Function

可以实现吗?

我的代码是:

#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 << "\n\n======================================================\n\n" << endl;

      myClass myObj(iObj,strObj);

      cout << "\n\n======================================================\n\n" << 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){
 ^

如何构建构造函数以便它可以区分重载构造函数的两个版本?

4 个答案:

答案 0 :(得分:2)

你可以在T const&T上重载构造函数,但是编译器不能选择构造函数来生成一对uncallavle构造函数:对于任何可行的参数,两者都不比另一个好。此外,您无法显式选择构造函数:构造函数不是正常函数,您无法转换它们。因此,在T const&T上重载构造函数完全没用。但是,可以基于rvalueness重载:让一个构造函数占用T const&而另一个构造函数占用T&&

也许你应该问一下你想要实现什么而不是你试图实现它...

答案 1 :(得分:1)

假设您有两个功能:

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);

类似于第一对功能。

您应该问自己的问题是导致您创建此类重载的要求是什么。他们是真正的要求吗?除非您的要求与众不同,否则您应该只能管理其中一项。

答案 2 :(得分:0)

好好打电话

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);

OR

myClass myObj(*(&iObj), strObj);

对于其他构造函数,我认为你不能调用它,总是会导致错误

答案 3 :(得分:-1)

你无法解决这样一个事实:你不能拥有两个采用相同参数的函数(构造函数或其他函数)。如果你这样做,你不会超载,你只是复制了这个功能。编译器不会通过引用而不是按值传递特殊异常。

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