考虑我们有两个类:
#include<iostream>
using namespace std;
class Base {
public:
Base(char c) {
cout << __FUNCTION__ <<":"<<__LINE__ << endl;
}
Base(double d) {
cout << __FUNCTION__ <<":"<<__LINE__ << endl;
}
~Base() {
cout << __FUNCTION__ <<":"<<__LINE__ << endl;
}
};
class Derived: public Base{
public:
Derived(int i, float f, char c):Base(c) {
cout << __FUNCTION__ <<":"<<__LINE__ << endl;
}
Derived(int i, float f, double d):Base(d) {
cout << __FUNCTION__ <<":"<<__LINE__ << endl;
}
~Derived() {
cout << __FUNCTION__ <<":"<<__LINE__ << endl;
}
};
这很简单易懂。现在,我们要实现一个新类DerivedWithParams:
class DerivedWithParams : public Base{
public:
struct Params {
int i;
int f;
char c;
double d;
};
DerivedWithParams(Params* params):Base(params->c) {
cout << __FUNCTION__ <<":"<<__LINE__ << endl;
}
DerivedWithParams(Params* params):Base(params->d) {
cout << __FUNCTION__ <<":"<<__LINE__ << endl;
}
~DerivedWithParams() {
cout << __FUNCTION__ <<":"<<__LINE__ << endl;
}
};
然而,在编译时,它会抱怨: 不能超载
似乎C ++不支持使用init参数列表重载。对此有何解决方法?
答案 0 :(得分:1)
重载函数必须具有不同的参数列表或const / not-const。
DerivedWithParams(Params* params):Base(params->c) {
cout << __FUNCTION__ <<":"<<__LINE__ << endl;
}
DerivedWithParams(Params* params):Base(params->d) {
cout << __FUNCTION__ <<":"<<__LINE__ << endl;
}
然而,这两个声明是相同的(DerivedWithParams(Params* params)
),因此编译器无法知道要调用哪个。
如果您打算创建某种可以包含不同类型值的结构,则需要一种方法来识别它实际包含的内容,并且只需要一种具有运行时逻辑的函数,例如
struct Params
{
enum Type
{
PARAM_I, PARAM_F, PARAM_C, PARAM_D;
};
Type type;
union
{
int i;
int f;
char c;
double d;
};
};
DerivedWithParams::DerivedWithParams(Params* params)
{
switch(params->type)
{
case Params::PARAM_I:
std::cout << params->i << std::endl;
break;
case Params::PARAM_F:
std::cout << params->f << std::endl;
break;
case Params::PARAM_C:
std::cout << params->c << std::endl;
break;
case Params::PARAM_D:
std::cout << params->d << std::endl;
break;
default:
std::cout << "Unknown" << std::endl;
break;
}
}
C ++ 17的类似功能由std::variant
提供,或者您可以使用Boost C ++库boost::variant
。
typedef std::variant<int, char, double> Params;
DerivedWithParams::DerivedWithParams(const Params ¶ms)
{
if (auto val = std::get_if<int>(¶ms))
{
std::cout << "int " << *val << std::endl;
}
else if (auto val = std::get_if<char>(¶ms))
{
std::cout << "char " << *val << std::endl;
}
else
{
std::cout << "Unknown" << std::endl;
break;
}
}
答案 1 :(得分:0)
它不能重载DerivedWithParams,因为编译器不知道选择哪个实现。
如果你用DerivedWithParams foo( &myParams );
来调用它会选择哪一个?
你需要做点什么来区分这两者。