可以基于引用形参类型重载构造函数吗?
Can we overload Constructor based on reference parameter type?
我知道我们不能像下面这样重载构造函数(唯一的区别是初始化列表):
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)。
相关文章:
- 非类型引用形参/实参
- 如何确保迭代器模板形参与模板类的模板形参具有相同的数据类型
- 如何在编译时通过模板形参默认值的名称/指针获取函数的类型
- 模板类的不同返回类型取决于类的形参
- 指向函数的指针vs作为模板非类型形参的函数
- 具有不同值类型模板形参的模板类的数组或向量
- 为什么模板非类型形参指针和引用实参需要是全局的
- 可以使用MemberFunction类型作为模板形参吗?
- c++ 03:是否有一种方法可以使一个类型每次被包含在模板形参中时都会编译成不同的类型?
- 将非const引用使用auto-keyword声明的lambda作为实参传递给std::函数形参类型
- 为什么标准不允许在模板形参列表中初始化依赖于常量的类型
- 在模板演绎中保持函数指针形参的完整类型
- 使用传入的字符串形参来访问类型中的内容
- 不能在模板专门化定义中将一个类的成员类型定义用作模板形参
- 使用函数返回值作为默认模板非类型形参
- 扩展非类型形参包来定义带有非类型形参的内部类模板是否合法?
- c++模板非类型形参的类型演绎
- 为静态成员函数模板非类型形参
- 带有不同类型的非类型形参的c++可变模板
- 非类型形参取决于它后面的实参