【发布时间】:2011-10-06 18:19:54
【问题描述】:
在下面的代码中,我的意图是根据传递给material 类对象的参数来调用kap(opacity 类)的两个重载构造函数之一:
class opacity{
private:
int mode;
double kap_const;
double kappa_array[10][10];
public:
opacity(double constkap); // picking the constructor sets the mode
opacity(char* Datafile);
double value(double T, double P); // will return a constant or interpolate
};
opacity::opacity(double constkap):mode(1){
kap_const = constkap;
}
opacity::opacity(char* Datafile):mode(2){
// read file into kappa_array...
}
class Matter {
public:
Matter(int i, double k, char* filename); // many more values are actually passed
opacity kap;
int x; // dummy thing
// more variables, call some functions
};
Matter::Matter(int i, double k, char * filename)
:x(k>0? this->kap(x): this->kap(filename) ) {
// ... rest of initialisation
}
但这不起作用:
test.cpp: In constructor 'Matter::Matter(int, double, char*)':
test.cpp:32:21: error: no match for call to '(opacity) (void*&)'
test.cpp:32:42: error: no match for call to '(opacity) (char*&)'
test.cpp:32:44: error: no matching function for call to 'opacity::opacity()'
test.cpp:32:44: note: candidates are:
test.cpp:20:1: note: opacity::opacity(char*)
test.cpp:20:1: note: candidate expects 1 argument, 0 provided
test.cpp:16:1: note: opacity::opacity(double)
test.cpp:16:1: note: candidate expects 1 argument, 0 provided
test.cpp:4:7: note: opacity::opacity(const opacity&)
test.cpp:4:7: note: candidate expects 1 argument, 0 provided
我尝试的第一件事,
Matter::Matter(int i, double k, char * filename)
:kap(k>0? k: filename) { // use k<0 as a flag to read from filename
// ... rest of initialisation
}
也失败了,因为“三元运算符的结果总是必须是相同的类型”出于编译时的原因,正如similar question 中所指出的那样(尽管似乎没有解释)。
现在,不优雅的解决方案是基于 kap 构造函数应接收的参数重载 Matter 构造函数,但这是 (1) 非常不优雅,特别是因为 Matter 构造函数需要许多变量并执行许多操作(因此很多代码将被复制只是为了改变构造函数初始化列表的kap 部分),并且(2)如果有另一个与Matter 一起使用的类,这可能会失控有不同的构造函数:对于具有 N 个 c'tors 的 M 类,一个以 N^ M 个组合结束。 ..
有人有什么建议或解决方法吗?提前致谢!
【问题讨论】:
-
我认为你必须向
opacity添加一个特殊的构造函数。要么接受一个 int 和文件名,要么一个默认构造函数,以便您可以在Matters 构造函数的主体中分配它。 -
为什么不将不透明度 kap 作为构造函数参数传递?您可以在调用构造函数之前使用三元运算符,然后创建一个不透明对象(可能在堆上)并在事务构造函数中传递一个指向它的指针。
-
@MooingDuck 啊,你是说 Johannes Schaub 写的吗?谢谢你的回答。
-
@John 如果我正确理解您的建议,有一个警告:“用户”(好吧,这只是我......)应该只使用他创建的
Matter对象,并且不必单独创建opacity实例——它只被Matter使用。从我使用public来看,这个意图可能并不清楚。
标签: c++ ternary-operator initializer-list constructor-overloading