【问题标题】:Can we overload Constructor based on reference parameter type?我们可以根据引用参数类型重载构造函数吗?
【发布时间】:2014-05-05 15:55:05
【问题描述】:

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

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){
 ^

如何转换我的构造函数,以便区分两个版本的重载构造函数?

【问题讨论】:

  • 编译器说不! ;) 也许你可以使用 typedefs,但我对此表示怀疑。
  • Typedef 对重载解析没有任何影响。
  • 你想要完成什么?如果要启用 C++11 “移动”而不是复制,请使用右值引用 (Type&amp;&amp;) 和 std::forward。否则,我看不出区分将引用和值传递给构造函数的任何意义,但也许我还不够努力。

标签: c++ constructor constructor-overloading


【解决方案1】:

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

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

【讨论】:

  • 我正在探索构造函数和初始化列表。于是,我的脑海里浮现出这样的想法。无法解决自己所以来这里问
【解决方案2】:

假设你有两个函数:

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

类似于第一对函数。

您应该问自己的问题是导致您创建此类重载的要求是什么。它们是真正的需求吗?除非您的要求不寻常,否则您应该能够仅使用其中一项进行管理。

【讨论】:

    【解决方案3】:

    好好打电话

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

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

    【讨论】:

      【解决方案4】:

      您无法绕过这样一个事实,即您不能拥有两个采用相同参数的函数(构造函数或其他函数)。如果你这样做,你并没有重载,你只是在复制函数。对于按引用而不是按值传递,编译器不会产生特殊异常。

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

      【讨论】:

      • Tying Overloading as myClass(const INT&amp; oInt,const STRING&amp; oStr):I(oInt),STR(oStr); myClass(const INT oInt,const STRING oStr); 显然参数的类型不同..请参考stackoverflow.com/questions/19539327/…
      猜你喜欢
      • 2011-01-28
      • 1970-01-01
      • 1970-01-01
      • 2015-04-20
      • 1970-01-01
      • 1970-01-01
      • 2016-06-05
      • 2022-01-05
      • 1970-01-01
      相关资源
      最近更新 更多